1

I am working on a C program that holds an array of pointer to structs. First the struct looks like this:

typedef struct
{
    int ID;
    char Name [20];
} rec;

Then I have a function that creates 1 of these structs:

struct rec* addEntry(){
    rec *temp;
    temp = malloc(sizeof(rec));
    printf("Please give me an ID number\n");
    scanf("%d", &temp->ID);

    printf("Now give me a name, maximum size for this is 20 characters\n");
    scanf("%s", &temp->Name);
    return temp;
}

Now this function works fine, it creates the struct and returns the pointer towards that struct I then have another function that creates a pointer array and fills it with pointers towards the structs:

struct rec* returnPointerToPointerArray()
{
    rec *pointerArray[2];
    pointerArray[0] = addEntry();
    pointerArray[1] = addEntry();
    printf("ID in main : %d\n", pointerArray[0]->ID);
    printf("Name in main : %s\n", pointerArray[0]->Name);
    printf("ID in main : %d\n", pointerArray[1]->ID);
    printf("Name in main : %s\n", pointerArray[1]->Name);
    pointerArray = malloc(sizeof(rec*)*2);
    return pointerArray;
}

For checking what happens I print the values that are stored at the places in the pointer array. At this point the values in the pointer array are correct.

However now I need to malloc room for this pointerArray and return a pointer to this pointer array, and that is where I get stuck.

The malloc line gives me an error:

error: incompatible types when assigning to type 'struct rec *[(sizetype)(size)]' from type 'void *'

Now to clarify I cannot use a linked list, I have to use an array of pointers instead. To add in my main loop I have another error in the following bit of code:

rec *pointerArray[2];
pointerArray = returnPointerToPointerArray(2);
printf("ID in main : %d\n", pointerArray[0]->ID);
printf("Name in main : %s\n", pointerArray[0]->Name);

This gives me the following error:

error: incompatible types when assigning to type 'struct rec *[2]' from type 'struct rec *'

Any help is more then welcome.

Thanks in advance, Ylva

6
  • 'pointerArray = malloc(sizeof(rec*)*2);' will not work and is anyway too late for what you intended since you already tried to store stuff in it. 'pointerArray' is an automatic-storage array, not a pointer, so you cannot malloc it. Commented Nov 3, 2014 at 18:40
  • But if I would return a pointer to that array would then the array not be gone since it is declared locally? Commented Nov 3, 2014 at 18:42
  • You have created pointers to struct in both functions without initializing them to point anywhere before using them. I wrote example below (had errors when first written, they have been tested now) Commented Nov 3, 2014 at 19:25
  • 1
    How nice of you to tell the user exactly how to exploit your buffer overflow. Commented Nov 3, 2014 at 20:22
  • struct rec is not defined anywhere. If you write struct rec * then that defines a new type, which is incompatible with rec . Commented Nov 3, 2014 at 21:26

3 Answers 3

1

This code doesn't make sense:

struct rec* returnPointerToPointerArray()
{
    rec *pointerArray[2];
    pointerArray[0] = addEntry();
    pointerArray[1] = addEntry();
    ...
    pointerArray = malloc(sizeof(rec*)*2);
    return pointerArray;
}

you're defining a stack array of pointers and assigning heap addresses for struct rec objects to them and afterwards trying to assign a heap-based array of two pointers to the address of the stack one. It will never compile.

Since your function is designed to return a pointer to an object of rec type (which will be the first of the two structures in the array I guess), you should first allocate on the heap the space for the two pointers (and thus use a double pointer) and then populate it/return it:

struct rec** returnPointerToPointerArray()
{
    rec **pointerArray;
    pointerArray = malloc(sizeof(rec*)*2); // Allocates 2 pointers
    pointerArray[0] = addEntry();
    pointerArray[1] = addEntry();
    ...
    return pointerArray;
}

Live Example

You should also free the allocated memory when you're done.

Sign up to request clarification or add additional context in comments.

3 Comments

At last, that looks more like it.
struct rec and rec are different types, and you only return a pointer to one of the entries.
@MattMcNabb That's correct too, sorry. I hadn't checked the return type in the first place. Fixed.
0

two problems here i identified:

First, you return before you copy the result to pointerArray.

pointerArray = malloc(sizeof(rec*)*2);
return pointerArray;

my suggestion is

struct rec** returnPointerToPointerArray()
{
    rec *pointerArray[2];
    pointerArray[0] = addEntry();
    pointerArray[1] = addEntry();
    printf("ID in main : %d\n", pointerArray[0]->ID);
    printf("Name in main : %s\n", pointerArray[0]->Name);
    printf("ID in main : %d\n", pointerArray[1]->ID);
    printf("Name in main : %s\n", pointerArray[1]->Name);
    rec **pointerArray2 = malloc(sizeof pointerArray);
    pointerArray2[0] = pointerArray[0];
    pointerArray2[1] = pointerArray[1];
    return pointerArray2;
}

notice that i have changed the variable name. you did make some other mistakes in your code.

Second,

rec *pointerArray[2];

is an array of pointer. the way to declare it is simply:

rec **pointerArray;

btw,

pointerArray = returnPointerToPointerArray(2);

this line should make the usage and declaration mismatch.

UPDATE:

found some error in my answer. you are returning an array of pointers.

10 Comments

would rec *pointerArray; not just create a pointer to a type rec? and not be an array of pointers to type rec?
@Ylva don't understand what you are worrying about. pointer and array are identical in typing system. rec *pointerArray; is a pointer pointing to some address. dereferencing it as an array by pointerArray[1] or so.
pointerArray = returnPointerToPointerArray(2); will indeed not work, should be pointerArray = returnPointerToPointerArray();
Yes, it would do exactly that, which is not what you need.
@Ylva yup, i did make mistakes. updated already. you should use double pointer since you want to point to an array.
|
0
typedef struct
{
    int ID;
    char Name [20];
} rec;

struct rec* returnPointerToPointerArray()
{
    rec *pointerArray[2];
    pointerArray[0] = addEntry();
    pointerArray[1] = addEntry();
    ...
    return pointerArray;
}

The return type is wrong for two reasons. The function returns a rec *, while it is declared to return a pointer to an undefined struct rec *. The type struct rec is not the same as the typedef rec!

Secondly, you should return a pointer to pointer to rec. When you return the array, the array name is converted to a pointer to its first element, which itself is a pointer.

Also, you have declared pointerArray as an actual array. You can not assign a new value to an array, and you can not return a pointer to a local variable. The lifetime of pointerArray ends when execution leaves this function, so a pointer to it will be entirely useless. Using such a pointer results in undefined behaviour.

You need to first allocate dynamic memory for the array, populate the array, and then return it:

rec** returnPointerToPointerArray()
{
  rec **pA = malloc (2 * sizeof *pA);
  if (pA) {
    pA[0] = addEntry();
    pA[1] = addEntry();
    if (pA[0]) {
      printf("ID in main : %d\n", pA[0]->ID);
      printf("Name in main : %s\n", pA[0]->Name);
    }
    if (pA[1]) {
      printf("ID in main : %d\n", pA[1]->ID);
      printf("Name in main : %s\n", pA[1]->Name);
    }
  }
  return pA;
}

Same problem here:

rec *pointerArray[2];
pointerArray = returnPointerToPointerArray(2);
printf("ID in main : %d\n", pointerArray[0]->ID);
printf("Name in main : %s\n", pointerArray[0]->Name);

You can not assign a new value to an array. You need to define pointerArray as a pointer to pointer:

rec **pointerArray;
pointerArray = returnPointerToPointerArray(/*2*/);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.