C 返回局部变量的引用

C 返回局部变量的引用,c,pointers,C,Pointers,可能重复: 通用条款4.4.4 c89 我主要调用一个函数来向函数传递一行文本。我想对它做些手术。然而,这意味着这条线没有用。因此,在get_string函数中,我复制内容并返回结果。唯一的问题是,该结果的内存将丢失,并指向意外的内容 我只是想知道,如果没有并仍然保留数据的顺序行,如何将结果传回 非常感谢你的建议 来自main的代码段: if(fgets(line_data, (size_t)STRING_SIZE, fp) == NULL) { fprintf(st

可能重复:

通用条款4.4.4 c89

我主要调用一个函数来向函数传递一行文本。我想对它做些手术。然而,这意味着这条线没有用。因此,在get_string函数中,我复制内容并返回结果。唯一的问题是,该结果的内存将丢失,并指向意外的内容

我只是想知道,如果没有并仍然保留数据的顺序行,如何将结果传回

非常感谢你的建议

来自main的代码段:

    if(fgets(line_data, (size_t)STRING_SIZE, fp) == NULL) {
        fprintf(stderr, "WARNING: Text error reading file line number [ %d ]\n", i);
    }

    if(get_string(line_data) != NULL) {
        if(strcmp(get_string(line_data), "END") == 0)
            break;
    }
    else {
        fprintf(stderr, "WARNING: Cannot get name of student at line [ %d ]\n", i);
    }

    /* Fill student info */
    strncpy(stud[i].name, line_data, (size_t)STRING_SIZE);
调用这个函数

char* get_string(char *line_data)
{
    char *quote = NULL;
    char result[STRING_SIZE] = {0};

    strncpy(result, line_data, (size_t)STRING_SIZE);

    /* Find last occurance */
    if((quote = strrchr(result, '"')) == NULL) {
        fprintf(stderr, "Text file incorrectly formatted for this student\n");
        return NULL;
    }
    /* Insert nul in place of the quote */
    *quote = '\0';

    /* Overwite the first quote by shifting 1 place */
    memmove(result - 1, result, strlen(result) + 1);

    return result;
}

您要为结果malloc内存:

char *result; result = malloc(STRING_SIZE);
正如您所拥有的,result的内存存在于堆栈上,因此仅在执行位于get_string()内的时间内


您还需要在返回NULL之前释放result,以防止内存泄漏。

您要为result对内存进行malloc操作:

char *result; result = malloc(STRING_SIZE);
正如您所拥有的,result的内存存在于堆栈上,因此仅在执行位于get_string()内的时间内


您还需要在返回NULL之前释放结果,以防止内存泄漏。

对于您的直接问题,请使用并告诉函数用户取消分配返回指针(这有点容易发生内存泄漏,因为在C中很容易忽略返回值),或者提供第二个参数作为接收缓冲区:

char* get_string( const char* line_data, char* receive_buf, size_t buf_size );
第三个参数是让函数知道接收缓冲区有多大


现在到您的代码-行
memmove(结果-1,结果,strlen(结果)+1)
会破坏堆栈。

对于您的直接问题,请使用并告诉函数用户取消分配返回指针(这很容易导致内存泄漏,因为在C中很容易忽略返回值),或者提供第二个参数作为接收缓冲区:

char* get_string( const char* line_data, char* receive_buf, size_t buf_size );
第三个参数是让函数知道接收缓冲区有多大

现在到您的代码-行
memmove(结果-1,结果,strlen(结果)+1)会破坏堆栈。

只需返回strdup(结果)。 它将分配和复制您的字符串。 但是,在外部函数中使用结果后,必须释放结果

您还可以在输入中获取一个缓冲区(其大小),并用所需内容填充它。

只需返回strdup(结果)。 它将分配和复制您的字符串。 但是,在外部函数中使用结果后,必须释放结果


您还可以在输入中获取缓冲区(其大小),并用所需内容填充它。

根据经验,您永远不应该返回指向函数局部变量的指针。您知道原因:一旦函数返回,为其变量分配的内存就可以用于其他用途。返回指向结果缓冲区的指针的想法本质上是错误的

您应该考虑是否真的需要保留引用字符串的副本。如果在调用get_string之前测试了“END”字符串会怎么样?如果以后需要引用和输出数据,这很容易做到。说:

printf("\"%s\"", student_record);
因此get_字符串实际上可以在缓冲区中工作,并返回错误代码(0表示成功)。因为您知道最终结果是一个更小的以nul结尾的字符串,所以您甚至不需要长度参数

int get_string(char* student_record);
如果确实需要保留带引号字符串的副本,则需要传递另一个缓冲区。我仍然会返回一个int来表示成功(0)或失败(比如-1)

我个人更喜欢让调用方分配自己的缓冲区。这样就有机会使用固定长度的缓冲区(更简单的内存管理)。例:


根据经验,永远不要返回指向函数局部变量的指针。您知道原因:一旦函数返回,为其变量分配的内存就可以用于其他用途。返回指向结果缓冲区的指针的想法本质上是错误的

您应该考虑是否真的需要保留引用字符串的副本。如果在调用get_string之前测试了“END”字符串会怎么样?如果以后需要引用和输出数据,这很容易做到。说:

printf("\"%s\"", student_record);
因此get_字符串实际上可以在缓冲区中工作,并返回错误代码(0表示成功)。因为您知道最终结果是一个更小的以nul结尾的字符串,所以您甚至不需要长度参数

int get_string(char* student_record);
如果确实需要保留带引号字符串的副本,则需要传递另一个缓冲区。我仍然会返回一个int来表示成功(0)或失败(比如-1)

我个人更喜欢让调用方分配自己的缓冲区。这样就有机会使用固定长度的缓冲区(更简单的内存管理)。例:


不确定,但我一直认为在函数内部分配是不好的做法。我认为应该由被调用方负责分配和释放内存。不确定,但我一直认为在函数内部分配内存是不好的做法。我认为应该是被调用方负责分配和释放内存。memmove在那里,因为get_字符串将删除双引号。i、 e.“Low,Lisa”将被返回为Low,Lisa。我不终止第二个,然后覆盖第一个。如果您知道更好的方法,我很乐意知道。
result-1
是无效地址。您正在覆盖堆栈上的其他内容。如何
memove(结果,结果+1,strlen(结果))?memmove在那里,因为get_字符串将删除双引号。i、 e.“Low,Lisa”将被返回为Low,Lisa。我不终止第二个,然后覆盖第一个。如果您知道更好的方法,我很乐意知道。
result-1
是无效地址。您正在覆盖堆栈上的其他内容。如何
memove(结果,结果+1,strlen(结果))