Dynamic allocation of array issue C
Asked Answered
N

3

7

To be clear, my code works perfectly. The issue that concerns me is that i am unsure of my array allocation type.

My task is rather simple: i am required to do some operations within a dynamically allocated array.

Yet, the values are already given in the array. So therefore i am required to add these values in it.

To keep my vector dynamically allocated and to avoid the following situation:

float *p;
 p = malloc(9 * sizeof(float));
* p=2;
* (p+1)=60;
* (p+2)=-23;
.
.
.
* (p+8)=9;

I tried doing this :

float *p;
p = malloc(9 * sizeof(float));
memcpy (p, (float[]) {2 ,60 ,-23, 55, 7, 9, -2.55, -66.9, 9}, 9 * sizeof(float));

Now I am unsure because memcpy copies a static allocated array into my p. My question is then: my array still remains dynamically allocated?

EDIT: My question refers to 2nd code.

Neuron answered 21/12, 2016 at 15:18 Comment(14)
You allocate 9 elements. Count how many fields you assign values to!Goodden
"memcpy copies a static allocated array into my p" - Where did you get this from? memcpy copies whatever you pass to it. The compound literal is a temporary automatic object.Goodden
@Olaf How is that, the 9 * sizeof(float) takes care of the amount, or did I miss anything? Agree, there is excess, but that should not be a problem, correct?Nianiabi
@Olaf this is what i have been taught. don't bash meNeuron
@SouravGhosh: I refer to the assignments. p[0] ... p[9] (no idea why OP uses the additions)! Accessing unallocated memory is always a problem!Goodden
@Sourav in the first code i didn't write all the values, as you can see it was just an e.g. , so Olaf rushed with his conclusionNeuron
@Olaf Ahh, right, I thought OP was avaoiding that, so I did not check that part. Your comment stands then. :)Nianiabi
@CatalinGhita: In which way did I "rush"?? And use the index-operator; it is the same as the additions (that's how it is defined!) and way easier to read. Also make the compound literal const, otherwise you might make the resulting code even worse.Goodden
@SouravGhosh: As I understand he wants to use a different approach for the first code. Strangely, he uses only 9 elements in the compound literal.Goodden
@ you made me count how many fields i used. in the first code i only used 3 fields and i realise it isn't correct. But again, i was looking for the main ideea, not the fact that i intentionally missed the other 6 values.Neuron
Nice Stuff @CatalinGhita. It is also good to check the return value of the void* pointer from malloc(), just to be super safe.Karlakarlan
@Karlakarlan yes thank you.Neuron
Suggest changing your post from *(p+9)=9; --> *(p+8)=9;. That coding mis-step is distracting.Shults
@chux you are right thank youNeuron
S
6

my array still remains dynamically allocated?

float *p;
p = malloc(9 * sizeof(float));
memcpy ( p, (float[]){2,60,-23,55,7,9,-2.55,-66.9,9}, 9 * sizeof(float));

Yes. The value of pointer p remains unchanged. It still points to the memory dynamically allocated.
p[0], the first element now has the value of 2.0f,
p[1], the next element now has the value of 60.0f, etc.


Some coding suggestions:

int main(void) {
#define COUNT 9
  float *p = malloc(sizeof *p * COUNT);
  if (p) {
    memcpy(p, (float[COUNT] ) { 2, 60, -23, 55, 7, 9, -2.55f, -66.9f, 9 },
        sizeof *p * COUNT);
    //...
  }
  free(p);
  return 0;
}
Shults answered 21/12, 2016 at 16:4 Comment(2)
why sizeof *p instead of sizeof(float) ?Neuron
@CatalinGhita With p as a pointer, p = malloc(sizeof *p * COUNT) is always right, easier for review and less work to update. If you saw code q = malloc(sizeof *q * COUNT) vs. r = malloc(sizeof (double) * COUNT), you would know the first is correct by just at the line. The 2nd would need you to search for the declaration of r to know if it is correct. With the 2nd, if the type pointer to should change, the coder is obligated to edit all related *alloc() calls.Shults
N
3

First of all, you don't have an(y) array, all you have a pointer to a memory of particular size.

Secondly, as you mentioned, (emphasis mine)

memcpy copies a static allocated array into my p

so, yes, the pointer still has (or points to) the dynamically allocated memory.

As we see from C11, chapter §7.24.2.1

The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. [...]

So, we can see, the objects themselves are not changed / replaced, it's only the contents that gets copied.

Nianiabi answered 21/12, 2016 at 15:20 Comment(2)
The compound literal is an array!Goodden
@Olaf Right. Basis of my answer: "my array....." which refers to p which is wrong. :)Nianiabi
G
0

If your initialisation values are constant, you can use a compound literal. However, the code is error-prone. If you forget one element in the literal, you will access the array out-of bounds. This invokes undefined behaviour.

Change three things:

// use a macro for the length. In general don't use magic numbers!
#define ARRAY_LEN 9

// change the compound literal to:
... (static const float [ARRAY_LEN]){ ... }

this avoids copying the literal every time your function executes. It also makes the literal immutable so the compiler can check if you try to assign values to it.

Note: mempcy does not "copy a static(ally) allocated array ...". Neither is that a requirement for your array, nor is the compound literal you use a static object, but automatic.

Caution: Always check the result of functions which can encounter an error if anything the function does is used for further processing. malloc can return a null pointer on error. Handle this situation appropriately!

Goodden answered 21/12, 2016 at 15:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.