c - 为什么这段修改字符串的代码不起作用?

标签 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;
}

最佳答案

首先,当你这样做时:

num = "123056";

您没有将字符串“123056”复制到 malloc() 分配的堆区域。在 C 中,为 char * 指针分配字符串文字值等同于将其设置为常量 - 即等同于:

char str[] = "123056";

因此,您刚刚完成的是您放弃了对 malloc() 分配的 100 字节堆区域的唯一引用,这就是为什么您的后续代码不打印的原因正确的值; 'p' 仍然指向由 malloc() 分配的堆区域(因为 num 在分配时指向它),但是num 不再如此。

我假设您实际上打算做的是将字符串“123056”复制到该堆区域。以下是如何做到这一点:

strcpy(num, "123056");

尽管出于各种原因,这是更好的做法:

strncpy(num, "123056", 100 - 1);  /* leave room for \0 (null) terminator */

如果你刚刚完成:

#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;
} 

你会得到正确的结果:

123456

你可以收缩这个操作:

p = p + 3;
*p = '4';

...并避免迭代指针,方法如下:

*(p + 3) = '4';

一些其他注意事项:

  • 虽然常见的文体实践,但将 malloc() 的返回值强制转换为 (char *) 是不必要的。 void *类型的转换和对齐由C语言保证。

  • 始终检查 malloc() 的返回值。如果堆分配失败(即您的内存不足),它将为 NULL,此时您的程序应该退出。

  • 根据实现情况,在某些情况下,malloc() 分配的内存区域可能包含陈旧的垃圾。分配后将其归零总是一个好主意:

    memset(num, 0, 100);
    
  • 永远不要忘记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;
}

关于c - 为什么这段修改字符串的代码不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/943191/

相关文章:

c++ - 错误 C2440 : '=' : cannot convert from 'int *' to 'int **'

c - 为什么在使用指向指针的指针时出现 malloc() 的段错误?

c - 指向字符串的指针数组

c - 如何在 C 中比较 char 指针和汽车

c - 如何在 C 中逐行读取 .txt?

c - 由于 glPushAttrib/glPopAttrib 已被弃用,保存 GL_DEPTH_FUNC 等属性的新方法是什么?

c++ - 编码 H.264 时 avcodec_encode_video2() 出现段错误

c - 如何将字符串数组的元素复制到另一个字符串变量?

c - &ch_array[0] 和 ch_array 有什么区别?

java - 在 SQL 插入之前转义 charArray 的最快方法