每个函数都可以返回自己的类型,但它不能返回指向在其函数堆栈中分配的内存的指针,因为函数堆栈被释放以在函数返回时重用并且不再可访问。任何访问其内存不再可访问的值的尝试都是未定义行为。
您有两个选择,或者 (1) 将 saida 作为参数传递给 text,(例如 char *text (char *s) { strcpy (s, "tata"); return s }(此时函数可以声明为 void,因为复制到 s 的字符将无论如何都可以在调用者中使用-并且不需要main()中的strcpy),或者(2)动态分配内存以在text()中保存"tata"并返回一个指向新块的指针内存。使用malloc, calloc, or realloc 分配的内存在函数返回后仍然存在,因为它分配在堆上并且具有程序持续时间(或直到它被释放)。
(注意:第三个选项是将palavra1声明为static字符数组,其大小足以容纳"tata"——这也将导致它在函数返回中幸存下来。但是通常应避免这种做法,而应优先选择前两个选项)
您可以以简单的方式动态分配,例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *text(void)
{
char *p = "tata", /* delcare pointer to string literal "tata" */
*palavra1 = malloc (strlen (p) + 1); /* allocate storage */
if (palavra1 != NULL) /* validate malloc succeeded */
strcpy (palavra1, p); /* copy "tata" to palavra1 */
return palavra1;
}
int main(void)
{
char saida[50],
*p = text(); /* must preserve pointer to beginning of memory */
/* validate p not NULL and length < 50 */
if (p != NULL && strlen (p) < sizeof saida) {
strcpy (saida, p); /* copy to saida */
printf ("%s\n", saida); /* output */
free (p); /* free allocated memory */
}
return 0;
}
使用/输出示例
$ ./bin/allocinfn
tata
内存使用/错误检查
在您编写的任何动态分配内存的代码中,对于分配的任何内存块,您都有 2 个职责:(1)始终保留指向起始地址的指针内存块,因此,(2) 当不再需要它时可以释放。
您必须使用内存错误检查程序来确保您不会尝试访问内存或写入超出/超出分配块的边界,尝试读取或基于未初始化的值进行条件跳转,最后,以确认您释放了已分配的所有内存。
对于 Linux,valgrind 是正常的选择。每个平台都有类似的内存检查器。它们都易于使用,只需通过它运行您的程序即可。
$ valgrind ./bin/allocinfn
==13720== Memcheck, a memory error detector
==13720== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==13720== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==13720== Command: ./bin/allocinfn
==13720==
tata
==13720==
==13720== HEAP SUMMARY:
==13720== in use at exit: 0 bytes in 0 blocks
==13720== total heap usage: 1 allocs, 1 frees, 5 bytes allocated
==13720==
==13720== All heap blocks were freed -- no leaks are possible
==13720==
==13720== For counts of detected and suppressed errors, rerun with: -v
==13720== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
始终确认您已释放已分配的所有内存并且没有内存错误。
(另请注意:main 的正确声明是 int main (void) 和 int main (int argc, char **argv)(您将看到用等效的 char *argv[] 编写)。注意: main 是 type int 的函数,它返回一个值。参见:C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)。另请参见:See What should main() return in C and C++?)
检查一下,如果您还有其他问题,请告诉我。