关于为变量分配内存,如果我创建一个变量并将其发送到另一个在该函数内分配内存的函数并将结果返回给我创建的变量,原始变量是否会拥有正确的分配内存?
这是一个关于评论的示例:
char** fnTest(char* string) {
char** rArray = malloc( 2 * sizeof(char*));
// Same example here. string was technically already malloc'd from main. Is the string here also malloc'd as well?
rArray[0] = string;
return rArray;
}
int main() {
char* inputString = malloc(5);
strcpy(inputString, "test");
// Question is in regards to pArray. Will this variable get malloc'd correctly?
char** pArray;
pArray = fnTest(inputString);
// Everythign will be free'd from another function, but to keep it simple I'm not including it here.
return 0;
}
最佳答案
如果您想在函数内进行分配,而不将分配的返回值分配回调用函数中,那么您不能简单地将指针传递给要分配的函数。为什么? C 是按值传递的,当变量作为参数传递时,函数会收到变量的副本,其地址与调用者中的原始变量的地址截然不同。对函数中变量所做的任何更改都不会在调用者中看到。
要处理这种情况,您可以传递变量的地址(例如指针)并更新内存中原始地址处的值。当您谈论已经是指针的变量时,同样适用,您必须将指针的地址作为参数传递,因此该函数接收一个包含原始指针地址的指针。然后,您可以使用原始指针地址进行分配/重新分配,并使更改在调用者中可见。一个简短的例子可能会有所帮助:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCHAR 64
void fntest (char **s)
{
void *tmp = realloc (*s, NCHAR); /* allocate - using realloc */
if (!tmp) /* validate every allocation */
perror ("realloc-*s");
*s = tmp; /* assign new block of memory (or NULL) to original address */
}
int main (void) {
char *string = NULL; /* must be initialized NULL */
fntest (&string); /* call fntest to allocate string */
if (string) { /* validate allocation succeeded */
strcpy (string, "some stuff"); /* copy some stuff */
printf ("string: %s\n", string); /* output it */
free (string); /* don't forget to free what you allocate */
}
}
示例使用/输出
$ ./bin/allocinfn
string: some stuff
内存使用/错误检查
$ valgrind ./bin/allocinfn
==7962== Memcheck, a memory error detector
==7962== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7962== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==7962== Command: ./bin/allocinfn2
==7962==
string: some stuff
==7962==
==7962== HEAP SUMMARY:
==7962== in use at exit: 0 bytes in 0 blocks
==7962== total heap usage: 1 allocs, 1 frees, 64 bytes allocated
==7962==
==7962== All heap blocks were freed -- no leaks are possible
==7962==
==7962== For counts of detected and suppressed errors, rerun with: -v
==7962== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
首选替代方案 - 利用函数 Return
虽然传递指针的地址没有任何问题(实际上在列表分配等中是必需的),但当简单地在单独的函数中分配时,您可以在函数内声明变量,分配需要空间,验证分配成功,然后返回指向新内存块的指针并在 main()
中将其分配回。这稍微简化了事情。例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCHAR 64
char *fntest (size_t size)
{
void *memptr = malloc (size); /* simply allocate size bytes */
if (!memptr) /* validate! */
perror ("malloc-memptr");
return memptr; /* return pointer to new block (or NULL) */
}
int main (void) {
char *string = fntest (NCHAR);
if (string) { /* validate allocation succeeded */
strcpy (string, "some stuff"); /* copy some stuff */
printf ("string: %s\n", string); /* output it */
free (string); /* don't forget to free what you allocate */
}
}
(输出和内存检查相同)
仔细查看,如果您仍有疑问,请告诉我。
关于c - 在另一个函数中分配内存的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54599538/