我想编写一个可以将c-string的内容复制到另一个c-string的函数。
#include <stdio.h>
#include <string.h>
void copy(char*,char*);
int main(){
char* string = "hello";
char* destination;
copy(destination,string);
printf("Source: %s\nDestination: %s",string,destination);
system("pause");
return 0;
}
void copy(char* dest, char* src){
dest = malloc(strlen(src)*sizeof(char)); //Crashes
while (*src){
*dest++ = *src++;
}
}
在函数调用工作之前分配内存时,在函数内部分配内存会导致程序崩溃:
char* destination = malloc(strlen(string)*sizeof(char)); //works
答案 0 :(得分:1)
在main()
函数中,您声明了destination
类型的变量char *
而未初始化它。然后,将destination
作为参数传递给copy()
函数。了解将哪些数据传递给copy()
非常重要。在这种情况下,由于destination
尚未初始化,因此我们不知道传递给copy()
的内容。在函数调用之前malloc()
时这很好,因为在那种情况下,destination
已经初始化。特别是,它的值是malloc()
返回的堆中的某个地址。
正如其他人所说,你还应该小心分配比src字符串长度多1个字节,以便为null终止符留出空间。
答案 1 :(得分:1)
主要问题已经以多种不同方式解释,与您将dest
传递给copy()
的方式有关。将指针传递给函数时,例如:
void copy(char* dest, char* src) {
该函数接收指针的副本,该指针将指向相同的地址,但将具有自己的的不同地址。因此,当您传递char *dest
时,copy()
函数会收到dest
指针的副本。当您在dest
中分配copy()
时,来电者main()
不知道dest
中copy()
的地址是什么,也无法访问内存由dest = malloc(strlen(src)*sizeof(char));
copy()
中的malloc
返回。
每当你在函数中分配内存时,如果你没有返回新分配的内存块的地址,你必须将地址指针传递给功能(不是指针的副本)。这样当您调用malloc
时,您将main()
的返回值(新内存块的起始地址)指定为指针在同一地址的值与#include <stdio.h>
#include <stdlib.h>
void copy (char **dest, char *src);
int main (int argc, char **argv) {
char *str = argc > 1 ? argv[1] :
"A quick brown fox jumps over the lazy dog.";
char *dest = NULL;
copy (&dest, str);
printf ("\n str : %s\n dest : %s\n\n", str, dest);
free (dest); /* free allocated memory */
return 0;
}
void copy (char **dest, char *src)
{
if (!src) { /* validate src string */
fprintf (stderr, "%s() error: invalid string 'src'.\n",
__func__);
return;
}
size_t len = 0;
char *p = src;
for (;*p; p++, len++) {} /* strlen */
/* allocate and validate -- every time */
if (!(*dest = malloc (len * sizeof **dest + 1))) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n",
__func__);
exit (EXIT_FAILURE);
}
p = *dest; /* copy src to dest */
for (; *src; src++) *p++ = *src;
*p = 0; /* null-terminate */
}
中一样。
如果你没有别的,请记住这条规则:如果要为传递给函数的指针分配内存,则必须 (1)返回新的地址给来电者;或(2)将指针的地址传递给分配函数。
以下是沿着类似方式的另一个例子,其中有几种不同的方法:
$ ./bin/copystr
str : A quick brown fox jumps over the lazy dog.
dest : A quick brown fox jumps over the lazy dog.
<强>输出强>
gcc
注意:如果您未使用__func__
,请将{{1}}更改为功能名称。
答案 2 :(得分:0)
问题在于copy
占用了地址 - destination
的当前值和source
的值。
然后它会覆盖destination
的当前值,结果为malloc
。
然后发生复制,malloc
内存丢失。
从复制中返回destination
的值,而不是将其传入。
或使用char **
和*。
char * copy( char* src){
char * dest = malloc( (1+strlen(src))*sizeof(char)); //Crashes
char * toReturn = dest;
while (*src){
*dest++ = *src++;
}
return toReturn;
}
或
void copy( char ** dest, char* src){
/* overwrite pointer value with the result of malloc */
char * toCopy;
(*dest) = malloc((1+strlen(src))*sizeof(char)); //Crashes
toCopy = *dest;
while (*src){
*toCopy++ = *src++;
}
}