我有两个版本的C代码。第一个有效,但第二个不起作用。
第二个的输出是分段错误,但我不知道为什么。
也许有人可以解释我的错误?我真的很感激。
这有效:
#include <stdio.h>
#include <stdlib.h>
void stringcpy(const char*, char*);
int main() {
const char * original = "C is fun.";
int size = sizeof(original) / sizeof(char*);
copy = (char*)malloc(sizeof(char) * 11 + 1);
stringcpy(original, copy);
printf("%sn", copy);
free(copy);
return 0;
}
void stringcpy(const char* original, char* copy) {
int i;
for(i = 0; *(original + i) != ' '; i++) {
*(copy + i) = *(original + i);
}
*(copy + i) = ' ';
}
这不起作用:
#include <stdio.h>
#include <stdlib.h>
void stringcpy(const char*, char*);
int main() {
const char * original = "C is fun.";
char * copy;
stringcpy(original, copy);
printf("%sn", copy);
free(copy);
return 0;
}
void stringcpy(const char* original, char* copy) {
int size = sizeof(original) / sizeof(char*);
copy = (char*)malloc(sizeof(char) * size + 1);
int i;
for(i = 0; *(original + i) != ' '; i++) {
*(copy + i) = *(original + i);
}
*(copy + i) = ' ';
}
int size = sizeof(original) / sizeof(char*);
将sizeof
应用于指针而不是此处的数组。这不会返回它指向的字符串的大小。strlen
是您应该在这里寻找的那个。将上面的行替换为此行(size
确定的解决方案)
int size = strlen(original); // better to use `size_t`
现在这是怎么回事 - 字符串文字是一个 char 数组,它衰减为指向第一个元素的指针,并且正在分配该指针值 - 您在其上应用 sizeof。这里没有数组的痕迹。要获取数组可以容纳的元素数,您必须传递数组本身而不是指针。
另一件事是 C 是按值传递的 - 所以这里要保留更改,要么将指针传递给指针,要么从函数传递分配的内存地址。
sizeof(char)
是1
所以你不需要明确地写它 - 你可以简单地写
copy = malloc(size + 1);
法典:
stringcpy(original, ©);
和
void stringcpy(const char* original, char** copy) {
int size = strlen(original);
*copy = malloc(size + 1);
int i;
for(i = 0; original[i] != ' '; i++) {
(*copy)[i] = original[i];
}
(*copy)[i] = ' ';
}
我已经向您展示了通过将指针变量的地址传递给另一个函数来解决问题的方法。或者(自己尝试)您可以从函数返回分配的内存块的地址并将其分配给copy
。这也行得通。
编辑:如果您不被允许更改函数签名,那么是的,除非您像之前在 case-1 中那样向copy
提供分配的内存,否则这是不可能的。
实现正确行为的另一种方法是这样做
char* stringcpy(const char* original) {
int size = strlen(original) ;
char* copy = malloc(size + 1);
int i;
for(i = 0; original[i] != ' '; i++) {
copy[i] = original[i];
}
copy[i]=0;
return copy;
}
并像这样使用它
copy = stringcpy(original);
这个答案中省略了几件事:
始终检查
malloc
的返回值 - 如果它返回 NULL,如果您对其进行检查,则不会取消引用它。不要强制转换返回类型的
malloc
-char*
转换为void*
转换是隐式的。
使用完动态分配的内存后,释放它。
在函数内分配的内存是从堆中分配的。 当您退出函数时,该内存将返回给系统,以便在您返回时不再分配该内存。