C 结构数组中的值变为垃圾值

C 结构数组中的值变为垃圾值,c,arrays,struct,C,Arrays,Struct,我有个问题让我很困惑。。。下面我调用了一个初始化函数: void Initialize (List *L) { char* initialize = "initialize"; int i; for (i=0; i<MAXLISTSIZE; i++) { strncpy(L->items[i].name,initialize,MAXNAMESIZE); L->items[i].name[MAXNAMESIZE - 1] =

我有个问题让我很困惑。。。下面我调用了一个初始化函数:

void Initialize (List *L) {
    char* initialize = "initialize";
    int i;

    for (i=0; i<MAXLISTSIZE; i++) {
       strncpy(L->items[i].name,initialize,MAXNAMESIZE);
       L->items[i].name[MAXNAMESIZE - 1] = '\0';
       L->items[i].grade = 0;
       printf("L->items[i].name = %s\n", L->items[i].name);
       printf("L->items[i].grade = %d\n", L->items[i].grade);
    }    
    L->count = 0;
}
我只是从main调用Initialize:

int main () {
    List *newList;

    /*call initialize function*/
    newList = callInitialize();

return 0;
}
callInitialize:

List *callInitialize () {
List *L;

List studentList;
L = &studentList;

Initialize(L); 

return L;
}

现在您已经发布了代码的其余部分,问题显而易见:

List *callInitialize () {
    List *L;

    List studentList;
    L = &studentList;

    Initialize(L); 

    return L;
}
在这个函数中,您可以创建一个局部变量studentList,您可以通过初始化来设置它

不幸的是,studentList变量的作用域在您退出callInitialize函数时结束。这就是为什么当你以后试图使用它时,它可能含有垃圾

尽管您评论说由于结构很小而不需要malloc,但是如果您希望数据的范围超出创建它的函数范围,您确实需要它

可能最小的更改解决方案是:

List *callInitialize (void) {
    List *L = malloc (sizeof (List));
    if (L != NULL)
        Initialize(&L); 
    return L;
}

然后请记住,调用方需要在某个时候释放它,除非malloc失败,并且此函数因此返回NULL。

既然您已经发布了代码的其余部分,问题就显而易见了:

List *callInitialize () {
    List *L;

    List studentList;
    L = &studentList;

    Initialize(L); 

    return L;
}
在这个函数中,您可以创建一个局部变量studentList,您可以通过初始化来设置它

不幸的是,studentList变量的作用域在您退出callInitialize函数时结束。这就是为什么当你以后试图使用它时,它可能含有垃圾

尽管您评论说由于结构很小而不需要malloc,但是如果您希望数据的范围超出创建它的函数范围,您确实需要它

可能最小的更改解决方案是:

List *callInitialize (void) {
    List *L = malloc (sizeof (List));
    if (L != NULL)
        Initialize(&L); 
    return L;
}

然后请记住,调用方需要在某个时候释放它,除非malloc失败,因此该函数返回NULL。

现在您发布了导致实际问题的函数,我们看到了问题所在:您返回的是超出范围的局部变量的地址!这是无效的

List * foo()
{
  List x;     // <--- x comes to life
  return &x;  // <--- x dies here...
}

int main()
{
  List * p = foo();  // ... but its address is used here!
  p->name ...        // dereferencing an invalid address!!
}
任何手动分配都需要附带清理程序:

void freeList(List * p)
{
  free(p);
}

现在,您发布了导致实际问题的函数,我们看到了问题所在:您正在返回超出范围的局部变量的地址!这是无效的

List * foo()
{
  List x;     // <--- x comes to life
  return &x;  // <--- x dies here...
}

int main()
{
  List * p = foo();  // ... but its address is used here!
  p->name ...        // dereferencing an invalid address!!
}
任何手动分配都需要附带清理程序:

void freeList(List * p)
{
  free(p);
}

callInitialize是什么?它与Initialize有什么关系???您在何处以及如何调用Initialize?1始终使用所有警告进行编译。2使用valgrind或类似的内存调试器。在你完成这两项工作并澄清之前不要发布,或者发布你收到的具体错误或警告。关键是,如果你自己做任何数量的调试工作,那么你要么发现问题,要么就可以问一个特定的问题,而不是转储整个代码,然后说这不起作用。@Kerrek SB很抱歉,我丢失了一个函数并添加了它。我意识到我不能期望发布我的代码并说修复它,这不是我的全部代码,但我认为对我的问题很重要的一切,我没有收到任何编译器警告。我花了很长时间试图让它自己工作,但没有能够想出一个解决办法。我不是一个经验丰富的程序员,也从来没有使用过内存调试器,但我会研究一下。再次抱歉,谢谢您抽出时间。@cdn88:不用担心!你的编译器是什么?我不确定你是否会收到警告,因为这是有点难以静态检测。然而,每当您看到任何类型的乱码输出时,您一定要检查内存调试器。在Linux上,valgrind非常易于使用,并且非常有用。使用调试符号编译以获得最佳结果。我确信其他人可以推荐Windows和MacOS的内存调试器。@Kerrek SB:我正在使用gcc和这些-Wall-ansi-pedantic-g编译器参数。我一定要去看看valgrind!我要是早点知道就好了。非常感谢。callInitialize是什么?它与Initialize有什么关系???您在何处以及如何调用Initialize?1始终使用所有警告进行编译。2使用valgrind或类似的内存调试器。在你完成这两项工作并澄清之前不要发布,或者发布你收到的具体错误或警告。关键是,如果你自己做任何数量的调试工作,那么你要么发现问题,要么就可以问一个特定的问题,而不是转储整个代码,然后说这不起作用。@Kerrek SB很抱歉,我丢失了一个函数并添加了它。我意识到我不能期望发布我的代码并说修复它,这不是我的全部代码,但我认为对我的问题很重要的一切,我没有收到任何编译器警告。我花了很长时间试图让它自己工作,但没有能够想出一个解决办法。我不是一个经验丰富的程序员,也从来没有使用过内存调试器,但我会研究一下。再次抱歉,谢谢您抽出时间。@cdn88:不用担心!你的编译器是什么?我不确定你是否会收到警告,因为这是有点难以静态检测。但是,什么时候?
一旦您看到任何类型的乱码输出,您肯定应该检查内存调试器。在Linux上,valgrind非常易于使用,并且非常有用。使用调试符号编译以获得最佳结果。我确信其他人可以推荐Windows和MacOS的内存调试器。@Kerrek SB:我正在使用gcc和这些-Wall-ansi-pedantic-g编译器参数。我一定要去看看valgrind!我要是早点知道就好了。非常感谢。很抱歉,我忘记了函数callInitialize,我把它添加到了帖子中。我不认为我需要malloc,因为我的struct items是固定大小的,不是很大。很抱歉,我忘记了callInitialize函数,我把它添加到了帖子中。我不认为我会需要malloc,因为我的struct项是固定大小的,不是很大。非常感谢!我忽略了列表的范围*L!我真的很抱歉在我的帖子中犯了错误,浪费了人们的时间。保重。别担心,这是最好的:-非常感谢!我忽略了列表的范围*L!我真的很抱歉在我的帖子中犯了错误,浪费了人们的时间。保重。别担心,最好的情况是:-