这里我动态地将内存分配给p以便我可以更改字符串的特定字符,但此代码挂在中间
int main()
{
char *p;
p=malloc(10*sizeof(char));
p="string";
p[0]='d';
printf("%s",p);
}
我尝试用p="string"
替换第5行的strcpy(p, "string")
,代码运行得很完美。任何人都可以告诉我背后的原因。
int main()
{
char *p;
p=malloc(10*sizeof(char));
strcpy(p, "string");
p[0]='d';
printf("%s",p);
}
答案 0 :(得分:2)
指针可以拥有资源(malloc),也可以指向另一个实体已拥有的资源。当您执行p="string";
时,您正在创建一个const char *
,您可以在其中分配字符指针p
,通过泄漏前一行中的malloc内存,在后一行中,你'只是替换malloc内存中的内容;前者是一个错误/问题,后者不是。值得注意的是,尽管泄漏资源/内存是不好的做法,但这并不是导致这种情况发生的原因。
你获得挂起的原因是因为你在C代码中进行的编辑试图编辑你是程序的只读内存空间(const char *
变量在这里被创建为不可变的字节数组{ {3}}程序存储器)。 segment进一步解释了这一点。
至于将所需的字节传递给malloc
,避免在表达式中使用类型是一种很好的做法:
const size_t count_required = 10;
char *p = malloc(sizeof(*p) * count_required);
// changing p's type to int* would also work without editing the malloc argument
当p的类型更改为float
,int
或任何其他类型时,表达式将继续正常工作而不做任何更改。
答案 1 :(得分:1)
该行
p="string";
将p
更改为指向只读字符串文字,从而泄漏过程中先前分配的内存。您无法写入字符串文字,因此p[0]='d';
可能会导致seg错误。
您的第二个版本,使用
strcpy(p, "string");
将只读字符串文字的内容复制到先前分配的内存中。您仍在使用此处动态分配的缓冲区,因此可以安全地在以后的代码中更改其内容。
另一个非常小的问题,sizeof(char)
保证为1,因此您可以简化malloc
来电
p=malloc(10);
答案 2 :(得分:1)
字符串不是C中的值。您不能使用赋值(=
)复制字符串,但可以指定指针(指针是“实际”值)。
要将字符串复制到新分配的内存中,您需要:
strcpy(p, "string");
您编写它的方式是,您使用静态字符串常量的地址覆盖malloc()
返回的指针。这会导致memory leak;避免它们是使C成为一种有价值的语言的挑战之一。
答案 3 :(得分:0)
首先,您的第一个程序中存在内存泄漏。你malloc
然后将指针指向另一个常量字符串。
其次,在第一个程序中,您正在修改CONSTANT字符串。但是第二个“CORRECT”程序,你复制了那个常量字符串并将其复制到分配的内存中。哪个,你可以自由改变。
答案 4 :(得分:0)
char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */
“amessage
是一个数组,大小足以容纳字符序列和'\0'
初始化它。数组中的单个字符可能会更改,但amessage将始终
参考相同的存储。另一方面,pmessage
是一个指针,初始化为指向a
弦常数;随后可以修改指针以指向其他位置,但结果是
如果您尝试修改字符串内容,则为undefined。“
courtsey K& R