//17、下面的程序会出现什么结果
#include
#include
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,”hello world”);
} int main( )
{
char *str=NULL;
getmemory(str);
printf(“%s/n”,str);
free(str);
return 0;
}
// 程序崩溃,getmemory中的malloc 不能返回动态内存, free()对str操作很危险
你上面提供的程序会导致运行时错误,具体原因如下:
1. 函数 getmemory
中的内存分配
在 getmemory
函数中,你尝试通过 malloc
分配内存并将其赋值给 p
:
void getmemory(char *p)
{ p = (char *) malloc(100); strcpy(p, "hello world");
}
- 这里的
p
是一个局部变量,传递给它的指针str
在main
函数中是NULL
。 - 当你调用
malloc
时,确实分配了 100 字节的内存,但这只改变了p
的值,原始的str
指针在main
函数中仍然是NULL
。函数结束后,p
被销毁,分配的内存的指针没有被保存。
2. main
函数中的操作
在 main
函数中,str
仍然是 NULL
:
int main()
{ char *str = NULL; getmemory(str); printf("%s/n", str); // 这里 str 仍然是 NULLfree(str); // 释放 NULL 的内存,虽然是安全的,但没有释放有效的内存return 0;
}
- 当你调用
printf("%s", str);
时,str
仍然是NULL
,这将导致未定义行为,程序可能会崩溃。 - 之后的
free(str);
调用虽然是安全的(释放 NULL 指针是安全的),但它不会释放任何有效的内存,因为str
仍然是NULL
。
3. 如何修复
如果你想让 getmemory
函数修改 str
,你需要将 str
的地址传递给 getmemory
。可以使用指向指针的指针:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void getmemory(char **p)
{ *p = (char *) malloc(100); strcpy(*p, "hello world");
}int main()
{ char *str = NULL; getmemory(&str); // 传递 str 的地址printf("%s\n", str); free(str); return 0;
}
总结
- 原始程序会导致崩溃,因为内存分配的结果没有返回给
main
中的str
。 - 通过传递指向指针的指针,可以使内存分配的结果有效地传回并使用。
指针和引用
python传参的值传递
让我们通过一个简单的例子来说明值传递和引用传递(或指针传递)之间的区别。
1. 值传递的例子
在 C 语言中,默认的参数传递方式是值传递。当你将一个变量传递给函数时,实际上是将该变量的副本传递过去,函数内对该副本的修改不会影响原始变量。
#include <stdio.h>void modifyValue(int a) {a = 10; // 这里只改变了 a 的副本
}int main() {int a = 3;printf("Before: a = %d\n", a); // 输出: 3modifyValue(a); // 传递 a 的值printf("After: a = %d\n", a); // 输出: 3 (未改变)return 0;
}
输出:
Before: a = 3
After: a = 3
2. 指针传递的例子
如果你想要在函数中修改原始变量的值,你需要传递该变量的地址。这时,你可以使用指针来实现。
#include <stdio.h>void modifyValue(int *p) {*p = 10; // 通过指针修改原始变量的值
}int main() {int a = 3;printf("Before: a = %d\n", a); // 输出: 3modifyValue(&a); // 传递 a 的地址printf("After: a = %d\n", a); // 输出: 10 (已改变)return 0;
}
输出:
Before: a = 3
After: a = 10
总结
-
值传递:在
modifyValue(int a)
中,a
是main
函数中a
的副本。对a
的修改不会影响原始变量。 -
指针传递:在
modifyValue(int *p)
中,p
是a
的地址,*p
允许你通过指针修改原始变量a
的值。
通过这种方式,你可以看到传递变量的值和地址(指针)所产生的不同效果。