为什么使用malloc创建的指针分配会导致分段错误

时间:2018-09-28 18:48:00

标签: c pointers

有人可以向我解释为什么在此处使用mallocmystrncat()中的指定行上导致段错误吗?我的印象是,我可以跨不同的堆栈框架访问堆的元素。有什么资料可以帮助我更好地理解这个主题?

谢谢。

编辑:

这是我的更新代码,仍然在该位置存在段错误。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define initial_malloc 20

char* mystrncat(char *dest, char *source, int n);

int main(void) {
    char *str1 = malloc(initial_malloc);
    char *str2 = malloc(initial_malloc);
    memset(str1, '\0', 20);
    memset(str2, '\0', 20);
    str1 = "hello";
    str2 = "World";

    mystrncat(str1, str2, 3);
    return EXIT_SUCCESS;
}

char *mystrncat(char *dest, char *source, int n) {
    int i, j, k, l;
    j = strlen(dest);
    for (i = 0; i < n && source[i] != '\0'; i++)
        ;
    for (k = j, l = 0; k < (j + i - 1); k++, l++) {
        dest[k] = source[l]; /* <-------runtime error here with malloc */
    }
    dest[k] = '\0';

    return dest;
}

2 个答案:

答案 0 :(得分:2)

=不复制字符串。它只为Poiner分配字符串文字的地址(在您的情况下)。字符串文字是只读的,任何写它们的尝试通常都以SEGFAULT结尾。

您需要将文字复制(使用strcpy)到str1中,然后才能连接它们。

这里根本不需要第二个字符串(str2)。

使用正确的类型(size_t)并尝试保持常量正确

顺便说一下,您这里分配的内存丢失了。

有点修改的版本

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define initial_malloc 20

char* mystrncat(char *, const char *, size_t);

int main(void) {
    char *str1 = malloc(initial_malloc);

    if(str1)
    {
        strcpy(str1, "hello");
        mystrncat(str1, "World", 3);
        printf("%s\n", str1);
        free(str1);
    }
    return EXIT_SUCCESS;
}

char *mystrncat(char *dest, const char *src, size_t n) 
{
    char *SavedDest = dest;

    while(*dest++);
    dest--;
    while(n && *src)
    {
        *dest++ = *src++;
        n--;
    }
    *dest = 0;
    return SavedDest;
}

答案 1 :(得分:2)

在调用str1并使它们指向字符串文字之前,请更改str2mystrncat。尝试修改str1所指向的内存具有未定义的行为,在您的情况下是分段错误。

由于您打算初始化分配的内存,请使用calloc(),它将以正确的大小更有效地执行初始化。您的代码未使用initial_malloc,因此如果将initial_malloc重新定义为其他值,它很可能会失败。

您应该输出结果字符串以检查其正确性。

还要注意,您的函数mystrncat与标准函数strncat具有不同的语义。如果这是您的意图,则名称mystrncat会引起误解。

这是具有标准语义的修改版本:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define initial_malloc 20

char *mystrncat(char *dest, const char *source, size_t n);

int main(void) {
    char *str1 = malloc(initial_malloc);
    char *str2 = malloc(initial_malloc);
    if (str1 == NULL || str2 == NULL) {
        printf("memory allocation failure\n");
        return EXIT_FAILURE;
    }
    strcpy(str1, "hello");
    strcpy(str2, "World");
    mystrncat(str1, str2, 3);
    printf("%s\n", str1);
    free(str1);
    free(str2);
    return EXIT_SUCCESS;
}

char *mystrncat(char *dest, const char *source, size_t n) {
    size_t i, j;

    for (i = 0, j = strlen(dest); i < n && source[i]; i++, j++) {
        dest[j] = source[i];
    }
    dest[j] = '\0';

    return dest;
}