有人可以向我解释为什么在此处使用malloc
在mystrncat()
中的指定行上导致段错误吗?我的印象是,我可以跨不同的堆栈框架访问堆的元素。有什么资料可以帮助我更好地理解这个主题?
谢谢。
编辑:
这是我的更新代码,仍然在该位置存在段错误。
#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;
}
答案 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
并使它们指向字符串文字之前,请更改str2
和mystrncat
。尝试修改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;
}