开发者

C - Can't initate a pointer that is passed as an argument

#include <stdio.h>
#include <stdlib.h>
typedef struct {
    unsigned length;
} List;
void init(List *l) {
    l = (List *) malloc(sizeof(List));
    l->length = 3;
}
int main(void) {
    List *list = NULL;
    init(list);
    if(list != NULL) {
     开发者_JAVA技巧   printf("length final %d \n", list->length);
        return 0;
    }
    return 1;
}

This is a simplified version of the code that is giving me problems. I am trying to construct the pointer *list from a method where *list is passed as an parameter.

I know I can make void init(List *l) work by changing it to void init(List **l) but this is for a class tutorial. I can't change the method arguments. I have spent four hours working on this.

I want to ensure that there is no way to make void init(List *l) work before I confront my professor.

Thanks in advance


You're passing a copy of the pointer to init, which is allocating memory, storing it in its local copy, and promptly leaking it when init returns. You cannot pass data back to the calling function this way. You need to either return the allocated data, or pass in a pointer to the pointer you want to modify, both of which involve modifying the function signature.

void init(List **l) {
    *l = (List *) malloc(sizeof(List));
    (*l)->length = 3;
}

init(&list);

Did the assignment specify that you have to allocate the List from within init? If not, you could always pass a pointer to an already allocated List object, and perform whatever initialization length = 3 is a place-holder for:

void init(List *l) {
  l->length = 3;
}

List list;
init(&list);
printf("length final %d \n", list.length);


The problem is that the pointer is passed by value, so you're changes are discarded. You really need a pointer to a pointer to do this correctly. As in you would do:

void init(List** l) {
   *l = (List*) malloc(sizeof(List));
   // ...
}

And when you call it, you would use init(&list) instead of init(list). Of course, in this case, it makes sense to just go ahead and return the result instead of using a pointer to a pointer:

List* init() {
    List* result = (List *) malloc(sizeof(List));
    result->length = 3;
    return result;
}

And then, with the above, you could simply use list = init();.

Note that in C++, you can use references instead of pointers, but mixing references and pointers is incredibly messy. Here, using a return-type is really the neatest thing to do.

If you absolutely have to use the existing signature, you can be sneaky and initialize the list, then in the init() function you can make the passed-in list's next pointer point to the list you actually want to create. Then, after init() has been called, you can take the next pointer and dispose of the original list object you created. Or you could always just have the first element by some dummy element.


this assignment is probably a good way to teach in a class the pass by value and pass by reference. If you want to maintain the constructor's signature you need to modify the main function.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
    unsigned length;
} List;


void init(List *l) {
    l->length = 3;
}
int main(void) {
    List list;// x = NULL;
    memset(&list,0,sizeof(List));
    init(&list);
    printf("length final %d \n", list.length);
    return 1;
}

Now here list is of type List and not address to List. the init() method passed the address of list and inside init you can change the value of the structure contents.

./a.out

length final 3


init needs to be passed a pointer to an existing List. I suspect that the real problem here is with your data structure. You have something called a List, that contains a length, but there's no list to be seen anywhere. List should probably contain a pointer to an array of the given length, and init should malloc that array and set the pointer. You will probably find this out when you ask the professor to correct his requirements which aren't broken -- if they were, he probably would have heard about it from past students and corrected them by now.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜