将内存分配给指针,该指针在函数内部作为参数

时间:2015-10-11 09:17:05

标签: c malloc strlen c-strings

我想编写一个可以将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

3 个答案:

答案 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()不知道destcopy()的地址是什么,也无法访问内存由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++;
    } 
}