Malloc() 和 free() 阻止我在 C 中按值传递结构
Malloc() and free() stopping me from passing structs by value in C
我正在做一个项目,但我一直遇到分段错误,而且结构的值没有被传递。弄清楚为什么让我发疯。我已经尝试用更简单的程序找出问题,我想我已经找到了问题,但我不确定如何解决它。
问题是,当我 "malloc" 一个结构,然后按值传递时,值丢失了。稍后添加 "free" 会产生分段错误。我没有尝试访问 "malloc()" 之前或 "free()" 之后的值,所以我很困惑为什么会这样。
这是问题的简单模型:
#include <stdlib.h>
#include <stdio.h>
struct structexample
{
int element;
};
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
teststruct->element = 10;
printf("teststruct element is %d in initStruct\n", teststruct->element);
*number = 5;
}
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
free(teststruct);
}
int main()
{
int number;
struct structexample teststruct;
initStruct(&teststruct, &number);
printtest(&teststruct, &number);
printf("teststruct element is %d in main()", teststruct.element);
return 0;
}
这会产生:
teststruct element is 10 in initStruct
teststruct element is -7967792 in printtest
Number is 5
Segmentation fault
我用 "gcc -Wall -pedantic -ansi" 编译程序,没有收到任何错误或警告。
当我注释掉 "malloc" 和 "free" 时,它会正确生成:
teststruct element is 10 in initStruct
teststruct element is 10 in printtest
Number is 5
如果我只注释掉 "free" 但保留 "malloc" ,这修复了分段错误,但结构的值仍然不正确。在这个简单的程序中,我并不真正需要 "malloc()" 和 "free()",但在我的大型项目中确实需要它们。如果我能让它们在这个更简单的程序中工作,那么我想我可以修复更大的程序。不幸的是,我在 Google 上找不到类似的问题。
您正在混合堆栈和堆
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
^ There is no need to use malloc, teststruct is on the stack
...
int main()
{
int number;
struct structexample teststruct;
initStruct(&teststruct, &number);
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
teststruct->element = 10;
printf("teststruct element is %d in initStruct\n", teststruct->element);
*number = 5;
}
你给这个函数传递了一个值,一个结构的地址,它完全忽略了。它使用 malloc
进行分配,但对它返回的地址不执行任何操作。它没有 return 它。它不会把它放在其他代码可以得到它的任何地方。所以你刚刚泄露了这个对象。
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
free(teststruct);
}
所以 printtest
将 teststruct
传递给 free
,因此它应该从 malloc
.
传递一个值 return
struct structexample teststruct;
initStruct(&teststruct, &number);
printtest(&teststruct, &number);
但是你把printtest
的地址传给了teststruct
,它是在栈上分配的。这不可能是对的。
您是否期待 initStruct
以某种方式移动 teststruct
?肯定不行。
只需从 printtest()
中删除 free()
行,使其看起来像这样:
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
}
发生分段错误是因为您试图释放堆栈上的内存!!
您还可以从 initStruct()
中删除 malloc()
行,因为它没有用:它正在为 struct structexample
分配 space 并将其地址返回到 [=16] =] wich 是在堆上分配的 struct structexample *
并传递给 initStruct()
,这意味着一旦调用 initStruct()
returns.
它将丢失
我正在做一个项目,但我一直遇到分段错误,而且结构的值没有被传递。弄清楚为什么让我发疯。我已经尝试用更简单的程序找出问题,我想我已经找到了问题,但我不确定如何解决它。
问题是,当我 "malloc" 一个结构,然后按值传递时,值丢失了。稍后添加 "free" 会产生分段错误。我没有尝试访问 "malloc()" 之前或 "free()" 之后的值,所以我很困惑为什么会这样。
这是问题的简单模型:
#include <stdlib.h>
#include <stdio.h>
struct structexample
{
int element;
};
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
teststruct->element = 10;
printf("teststruct element is %d in initStruct\n", teststruct->element);
*number = 5;
}
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
free(teststruct);
}
int main()
{
int number;
struct structexample teststruct;
initStruct(&teststruct, &number);
printtest(&teststruct, &number);
printf("teststruct element is %d in main()", teststruct.element);
return 0;
}
这会产生:
teststruct element is 10 in initStruct
teststruct element is -7967792 in printtest
Number is 5
Segmentation fault
我用 "gcc -Wall -pedantic -ansi" 编译程序,没有收到任何错误或警告。
当我注释掉 "malloc" 和 "free" 时,它会正确生成:
teststruct element is 10 in initStruct
teststruct element is 10 in printtest
Number is 5
如果我只注释掉 "free" 但保留 "malloc" ,这修复了分段错误,但结构的值仍然不正确。在这个简单的程序中,我并不真正需要 "malloc()" 和 "free()",但在我的大型项目中确实需要它们。如果我能让它们在这个更简单的程序中工作,那么我想我可以修复更大的程序。不幸的是,我在 Google 上找不到类似的问题。
您正在混合堆栈和堆
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
^ There is no need to use malloc, teststruct is on the stack
...
int main()
{
int number;
struct structexample teststruct;
initStruct(&teststruct, &number);
void initStruct(struct structexample * teststruct, int * number)
{
teststruct = malloc(sizeof(struct structexample));
teststruct->element = 10;
printf("teststruct element is %d in initStruct\n", teststruct->element);
*number = 5;
}
你给这个函数传递了一个值,一个结构的地址,它完全忽略了。它使用 malloc
进行分配,但对它返回的地址不执行任何操作。它没有 return 它。它不会把它放在其他代码可以得到它的任何地方。所以你刚刚泄露了这个对象。
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
free(teststruct);
}
所以 printtest
将 teststruct
传递给 free
,因此它应该从 malloc
.
struct structexample teststruct;
initStruct(&teststruct, &number);
printtest(&teststruct, &number);
但是你把printtest
的地址传给了teststruct
,它是在栈上分配的。这不可能是对的。
您是否期待 initStruct
以某种方式移动 teststruct
?肯定不行。
只需从 printtest()
中删除 free()
行,使其看起来像这样:
void printtest(struct structexample * teststruct, int * number)
{
printf("teststruct element is %d in printtest\n", teststruct->element);
printf("Number is %d\n", *number);
}
发生分段错误是因为您试图释放堆栈上的内存!!
您还可以从 initStruct()
中删除 malloc()
行,因为它没有用:它正在为 struct structexample
分配 space 并将其地址返回到 [=16] =] wich 是在堆上分配的 struct structexample *
并传递给 initStruct()
,这意味着一旦调用 initStruct()
returns.