我有这段代码:
1 #include <stdio.h>
2 #include <string.h>
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&#39; s或1&#39; s)并返回一个int数组,每个元素为0或1。
如果我尝试打印阵列&#34;结果&#34;因为我在for循环中创建它(使用printf(&#34;%d&#34;,result [i]))它将返回000011110000 .....
但是我遇到了返回类型的问题,它给了我一个警告:函数返回局部变量的地址。 main中的for循环只打印垃圾值。
答案 0 :(得分:3)
result
变量是getNbits的本地变量。这意味着只要函数返回就可以释放它。
不要将LOCAL变量的地址作为指针返回 - 它可以并且将被取消分配。
相反,分配这样的整数:
int* retVal = malloc(sizeof(int) * 10);
然后从getNbits返回retVal
。
请参阅此网址:
http://ww2.cs.mu.oz.au/~mgiuca/253/malloc.html
注意:如果您使用上面的malloc
,则还必须使用free
来释放
在不再需要内存后分配内存:
/* When the array is no longer needed */
free(x);
在空闲时,变量名称为x
,因为这是分配的左值
从调用getNbits。不要从getNbits调用free
。
答案 1 :(得分:2)
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()
函数内部。在函数外部传递对此数组的引用并不是一个好主意;由于阵列正式驻留的堆栈空间将用于其他目的。
通过在堆上分配数组可以更好地完成相同的操作:
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()。
答案 2 :(得分:0)
在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 []等函数传递为静态存储,因此地址不在堆栈中。这有效,但不是线程安全的,无论如何都必须复制存储在数据结构中的任何值。
如果您确实编写了一个动态构造数据结构的库函数,那么将它与例程配对以整理,而不是将实现细节泄漏到调用者程序中!