Mik*_*son 5 c pointers char segmentation-fault access-violation
对于c样式的字符串,如何将字符指针指向的内存地址赋予char?例如,在下面的示例中,我想将num更改为"123456",因此我尝试将p设置为'0'所在的数字,并尝试用'4'覆盖它.谢谢.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* num = (char*)malloc(100);
char* p = num;
num = "123056";
p = p+3; //set pointer to where '4' should be
p = '4';
printf("%s\n", num );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*hov 13
首先,当你这样做时:
num = "123056";
Run Code Online (Sandbox Code Playgroud)
您没有将字符串"123056"复制到分配的堆区域malloc()
.在C中,指定一个char *
字符串文字值相当于将其设置为常量 - 即相同于:
char str[] = "123056";
Run Code Online (Sandbox Code Playgroud)
那么,你刚刚完成的是你已经放弃了对分配的100字节堆区域的唯一引用malloc()
,这就是你的后续代码没有打印正确值的原因; ' p
'仍指向分配的堆区域malloc()
(因为num
在分配时指向它),但num
不再存在.
我假设您实际上打算将字符串"123056" 复制到该堆区域.以下是如何做到这一点:
strcpy(num, "123056");
Run Code Online (Sandbox Code Playgroud)
虽然,出于各种原因,这是更好的做法:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Run Code Online (Sandbox Code Playgroud)
如果你刚刚完成:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num = malloc(100);
char *p = num;
strncpy(num, "123056", 100 - 1);
p = p + 3;
*p = '4';
printf("%s\n", num);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你会得到正确的结果:
123456
Run Code Online (Sandbox Code Playgroud)
您可以签订此操作合同:
p = p + 3;
*p = '4';
Run Code Online (Sandbox Code Playgroud)
...并避免迭代指针,方法如下:
*(p + 3) = '4';
Run Code Online (Sandbox Code Playgroud)
其他几点说明:
虽然常见文体实践,铸造的返回值malloc()
来(char *)
是不必要的.void *
C语言保证了类型的转换和对齐.
总是检查的返回值malloc()
.如果堆分配失败(即你的内存不足),它将为NULL,此时你的程序应该退出.
根据实现,malloc()
在某些情况下,分配的内存区域可能包含陈旧垃圾.分配后将其归零是一个好主意:
memset(num, 0, 100);
Run Code Online (Sandbox Code Playgroud)别忘了free()
你的堆!在这种情况下,程序将退出,操作系统将清理您的垃圾,但如果您没有养成这种习惯,您将立即泄漏内存.
所以,这是"最佳实践"版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num, *p;
/*
* Don't take 1-byte chars for granted - good habit to get into.
*/
num = malloc(sizeof(char) * 100);
if(num == NULL)
exit(1);
memset(num, 0, sizeof(char) * 100);
p = num;
strncpy(num, "123056", 100 - 1);
*(p + 3) = '4';
printf("%s\n", num);
free(num);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 12
该代码不起作用,仅仅因为该行:
num = "123056";
Run Code Online (Sandbox Code Playgroud)
更改num
指向远离分配的内存(并p
保持指向该内存,因此它们不再是相同的位置)到最可能的只读内存.您不能更改属于字符串文字的内存,它是未定义的行为.
您需要以下内容:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *num = malloc (100); // do not cast malloc return value.
char *p = num;
strcpy (num, "123056"); // populate existing block with string.
p = p + 3; // set pointer to where '0' is.
*p = '4'; // and change it to '4'.
printf ("%s\n", num ); // output it.
return 0;
}
Run Code Online (Sandbox Code Playgroud)