在C中返回int数组
我有这个代码:
1 #include 2 #include 3 #define LENGTH(a) sizeof(a)/sizeof(a[0]); 4 5 int *getNbits(int, int, char *); 6 7 int main() { 8 char ins[] = "00001111000011110000111100001111"; 9 int *x = getNbits(0, 32, ins); 10 11 for (int i = 0; i < LENGTH(x) ; i++){ 12 13 printf("%d", *(x + i)); 14 } 15 return 0; 16 } 17 18 int* getNbits(int start, int offset, char instr[33]) { 19 20 int result[offset - 1]; 21 for (int i = 0; i < offset; i++) { 22 result[i] = instr[i + start] == '1' ? 1 : 0; //- '0'; 23 } 24 return result; 25 }
基本上,getNbits()获取一个chars数组(0或1),并返回一个int数组,每个元素为0或1。
如果我尝试打印数组“结果”,因为我在for循环中创建它(使用printf(“%d”,result [i]))它将返回000011110000 …..
但是我遇到了返回类型的问题,它给了我一个警告:函数返回局部变量的地址。 main中的for循环只打印垃圾值。
result
变量是getNbits的本地变量。 这意味着只要函数返回就可以释放它。
不要将LOCAL变量的地址作为指针返回 – 它可以并且将被释放。
相反,像这样分配整数:
int* retVal = malloc(sizeof(int) * 10);
然后从getNbits返回retVal
。
看到这个url:
http://ww2.cs.mu.oz.au/~mgiuca/253/malloc.html
注意:如果您使用上面的malloc
,您还必须使用free
来释放不再需要的内存:
/* When the array is no longer needed */ free(x);
在free时,变量名是x
因为这是从getNbits调用中分配的左值。 不要free
从getNbits打电话。
int* getNbits(int start, int offset, char instr[33]) { int result[offset - 1]; for (int i = 0; i < offset; i++) { result[i] = instr[i + start] == '1' ? 1 : 0; //- '0'; } return result; }
int数组result
在堆栈上声明(默认情况下)。 这导致它的范围(寿命)限制在getNbits()
函数内部。 在函数外部传递对该数组的引用并不是一个好主意; 由于arrays正式驻留的堆栈空间将用于其他目的。
通过在堆上分配数组可以更好地完成相同的操作:
int* getNbits(int start, int offset, char instr[33]) { int *result = malloc(offset * sizeof(*result)); // As indicated by BLUEPIXY's comment if(NULL == result) { fprintf(stderr, "malloc() failed\n"); goto CLEANUP; } for (int i = 0; i < offset; i++) { result[i] = instr[i + start] == '1' ? 1 : 0; //- '0'; } CLEANUP: return result; }
当然,在上面的例子中,当不再需要将分配的内存返回给堆时,getNbits()的调用者必须记住在返回的数组上调用free()。
它更简单,更不容易出错,在main中分配数组,您可以在其中调用结果数组。
int result[ sizeof ins]; /* Size known at compile time */ getNbits(0, 32, ins, result); /* Pass arrays by reference */
void getNbits(int start, int offset, const char instr[], int result[]) {
这是在堆栈上使用automatic
存储,当例程返回时自动回收。 正如问题中的代码所示,printf在堆栈上分配的变量将覆盖result指向的值。
一个优点是推广了getNbits子例程,因此它适用于较长版本的“ins”。 当然,真正的程序会有getNbits返回的错误状态来捕获错误。
对于malloc,函数中的内存以及调用者负责释放不是很好的做法,它可能会泄漏或稍后被释放多次,使用更复杂的程序,这些通常很难追踪错误。
传统代码通常定义结构或数组,从int result []等函数传递为静态存储,因此地址不在堆栈中。 这有效,但不是线程安全的,并且无论如何都必须复制存储在数据结构中的任何值。
如果您确实编写了一个动态构造数据结构的库函数,那么将它与例程配对以进行整理,而不是将实现细节泄漏到调用者程序中!