void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
请问运行Test函数会有什么样的结果?
答:程序崩溃。因为GetMemory并不能传递动态内存,Test函数中的 str一直都是 NULL。strcpy(str, "hello world");将使程序崩溃。
//////////////////////////////////////////////////////////////
2
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
请问运行Test函数会有什么样的结果?
答:可能是乱码。因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。
//////////////////////////////////////////////////////////////////////////////
3.
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行Test函数会有什么样的结果?
答:(1)能够输出hello(2)内存泄漏
//////////////////////////////////////////////////////////////////////////4.
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
}
请问运行Test函数会有什么样的结果?
答:篡改动态内存区的内容,后果难以预料,非常危险。因为free(str);之后,str成为野指针,if(str != NULL)语句不起作用。
11 个解决方案
#1
1。
函数传值操作,所以调用没有把str改变,同时macol的内存没有释放
2。
函数退出空间一释放,所以不能确定
3。
如1
函数传值操作,所以调用没有把str改变,同时macol的内存没有释放
2。
函数退出空间一释放,所以不能确定
3。
如1
#2
1.传值操作,这样void GetMemory(char *(&p))就没问题
2.
3.同上
2.
3.同上
#3
1.形参的传递实际上是传递参数的地址的拷贝,故在函数内部不能改变真实参数的地址。考虑要将真实参数的地址传入,可用楼上的void GetMemory(char *(&p))
2.p是一个局部变量她的作用范围只是在函数char *GetMemory(void)内部,他在函数返回时已经释放
3.free(*p)应该在用完以后,至于内存泄漏,是因为,你在分配内存的时候是吧内存分配给了一个指向指针的指针,返回后,str的地址指向是分配内存的,你释放str就会泄漏
2.p是一个局部变量她的作用范围只是在函数char *GetMemory(void)内部,他在函数返回时已经释放
3.free(*p)应该在用完以后,至于内存泄漏,是因为,你在分配内存的时候是吧内存分配给了一个指向指针的指针,返回后,str的地址指向是分配内存的,你释放str就会泄漏
#4
代楼主问一下:
char * GetMemory(int num)
{
return (char *)malloc(num);
}
char *str;
str = GetMemory(100);
====================================
void GetMemory(char *p)
{
p = (char *)malloc(num);
}
char *str;
GetMemory(str);
都是char *,为什么?
char * GetMemory(int num)
{
return (char *)malloc(num);
}
char *str;
str = GetMemory(100);
====================================
void GetMemory(char *p)
{
p = (char *)malloc(num);
}
char *str;
GetMemory(str);
都是char *,为什么?
#5
up
#6
事实上,
1.在 Debug 时一定崩溃,在 Release 时有可能不崩溃
4.在 Debug 时可能会有警告,但通常不会有危险
1.在 Debug 时一定崩溃,在 Release 时有可能不崩溃
4.在 Debug 时可能会有警告,但通常不会有危险
#7
受益
#8
这是林锐的《高质量c编程》里的一段……呵呵呵
有空可以看看………………upupup
有空可以看看………………upupup
#9
实际上对于真正了解栈内存和堆内存分配的人,这根本不是问题的问题。
#10
考虑了很久终于想通了。(不当之处还请指出)
1.
首先str是一个指针型的变量,该变量的初值为NULL;
接着将该变量的值(即NULL),而非变量本身,作为参数传递给GetMemory的变量p;
因此一进入GetMemory,变量p即有一初值NULL;
然后在堆中分配内存块,并将块的首地址赋给p;
因此p的值改变了,但GetMemory没有对变量str进行任何操作,其值当然不会变,仍为NULL;
因此出错!
简单说就是,参数的传递传的是变量的值,而非变量本身,变量本身只能由变量的内存地址唯一标识,而变量名只是一个助记符,有时代表变量的值,如作为右值或参数,有时代表变量本身,如作为左值。
4.
建议每次释放完指针指向的内存空间后将指针的值设为NULL。
1.
首先str是一个指针型的变量,该变量的初值为NULL;
接着将该变量的值(即NULL),而非变量本身,作为参数传递给GetMemory的变量p;
因此一进入GetMemory,变量p即有一初值NULL;
然后在堆中分配内存块,并将块的首地址赋给p;
因此p的值改变了,但GetMemory没有对变量str进行任何操作,其值当然不会变,仍为NULL;
因此出错!
简单说就是,参数的传递传的是变量的值,而非变量本身,变量本身只能由变量的内存地址唯一标识,而变量名只是一个助记符,有时代表变量的值,如作为右值或参数,有时代表变量本身,如作为左值。
4.
建议每次释放完指针指向的内存空间后将指针的值设为NULL。
#11
1。理解函数参数的值传递与引用传递
2。理解变量的作用域
3。动态分配的存储区要释放
4。动态分配的存储区释放后,指针不会自动设置为0
2。理解变量的作用域
3。动态分配的存储区要释放
4。动态分配的存储区释放后,指针不会自动设置为0
#1
1。
函数传值操作,所以调用没有把str改变,同时macol的内存没有释放
2。
函数退出空间一释放,所以不能确定
3。
如1
函数传值操作,所以调用没有把str改变,同时macol的内存没有释放
2。
函数退出空间一释放,所以不能确定
3。
如1
#2
1.传值操作,这样void GetMemory(char *(&p))就没问题
2.
3.同上
2.
3.同上
#3
1.形参的传递实际上是传递参数的地址的拷贝,故在函数内部不能改变真实参数的地址。考虑要将真实参数的地址传入,可用楼上的void GetMemory(char *(&p))
2.p是一个局部变量她的作用范围只是在函数char *GetMemory(void)内部,他在函数返回时已经释放
3.free(*p)应该在用完以后,至于内存泄漏,是因为,你在分配内存的时候是吧内存分配给了一个指向指针的指针,返回后,str的地址指向是分配内存的,你释放str就会泄漏
2.p是一个局部变量她的作用范围只是在函数char *GetMemory(void)内部,他在函数返回时已经释放
3.free(*p)应该在用完以后,至于内存泄漏,是因为,你在分配内存的时候是吧内存分配给了一个指向指针的指针,返回后,str的地址指向是分配内存的,你释放str就会泄漏
#4
代楼主问一下:
char * GetMemory(int num)
{
return (char *)malloc(num);
}
char *str;
str = GetMemory(100);
====================================
void GetMemory(char *p)
{
p = (char *)malloc(num);
}
char *str;
GetMemory(str);
都是char *,为什么?
char * GetMemory(int num)
{
return (char *)malloc(num);
}
char *str;
str = GetMemory(100);
====================================
void GetMemory(char *p)
{
p = (char *)malloc(num);
}
char *str;
GetMemory(str);
都是char *,为什么?
#5
up
#6
事实上,
1.在 Debug 时一定崩溃,在 Release 时有可能不崩溃
4.在 Debug 时可能会有警告,但通常不会有危险
1.在 Debug 时一定崩溃,在 Release 时有可能不崩溃
4.在 Debug 时可能会有警告,但通常不会有危险
#7
受益
#8
这是林锐的《高质量c编程》里的一段……呵呵呵
有空可以看看………………upupup
有空可以看看………………upupup
#9
实际上对于真正了解栈内存和堆内存分配的人,这根本不是问题的问题。
#10
考虑了很久终于想通了。(不当之处还请指出)
1.
首先str是一个指针型的变量,该变量的初值为NULL;
接着将该变量的值(即NULL),而非变量本身,作为参数传递给GetMemory的变量p;
因此一进入GetMemory,变量p即有一初值NULL;
然后在堆中分配内存块,并将块的首地址赋给p;
因此p的值改变了,但GetMemory没有对变量str进行任何操作,其值当然不会变,仍为NULL;
因此出错!
简单说就是,参数的传递传的是变量的值,而非变量本身,变量本身只能由变量的内存地址唯一标识,而变量名只是一个助记符,有时代表变量的值,如作为右值或参数,有时代表变量本身,如作为左值。
4.
建议每次释放完指针指向的内存空间后将指针的值设为NULL。
1.
首先str是一个指针型的变量,该变量的初值为NULL;
接着将该变量的值(即NULL),而非变量本身,作为参数传递给GetMemory的变量p;
因此一进入GetMemory,变量p即有一初值NULL;
然后在堆中分配内存块,并将块的首地址赋给p;
因此p的值改变了,但GetMemory没有对变量str进行任何操作,其值当然不会变,仍为NULL;
因此出错!
简单说就是,参数的传递传的是变量的值,而非变量本身,变量本身只能由变量的内存地址唯一标识,而变量名只是一个助记符,有时代表变量的值,如作为右值或参数,有时代表变量本身,如作为左值。
4.
建议每次释放完指针指向的内存空间后将指针的值设为NULL。
#11
1。理解函数参数的值传递与引用传递
2。理解变量的作用域
3。动态分配的存储区要释放
4。动态分配的存储区释放后,指针不会自动设置为0
2。理解变量的作用域
3。动态分配的存储区要释放
4。动态分配的存储区释放后,指针不会自动设置为0