无法返回int数组

我想只使用studio.h库通过使用数组来存储余数但从十进制数转换为二进制数但结果不正确,也许我有内存分配问题或返回值有误,请帮我检查一下。 非常感谢!

#include  int n = 0; int* DecimalToBinary(int number){ int a[10]; while(number!=0){ a[n++] = number%2; number/=2; } return a; } void main(){ int *d1 = DecimalToBinary(5); int *d2 = DecimalToBinary(10); for(int i = n-1 ;i>=0;i--) printf(" %d",d1[i]); printf("\n"); for(int i = n-1 ;i>=0;i--) printf(" %d",d2[i]); } 

您正在返回指向本地分配的数组的指针。 它在堆栈上分配,并在函数返回时消失,使指针指向垃圾。

你有几个选择。 您可以传入一个数组来填充:

 void DecimalToBinary(int result[10],int number){ while(number!=0){ result[n++] = number%2; number/=2; } return result; } // usage example: int b[10]; DecimalToBinary(b, 42); 

或者您可以在堆上分配一个数组:

 int* DecimalToBinary(int number){ int *a = (int *)malloc(sizeof(int) * 10); while(number!=0){ a[n++] = number%2; number/=2; } return a; } // usage example int *b = DecimalToBinary(42); free(b); // when finished with it 

或者您可以将数组包装在结构中:

 typedef struct { int b[10]; } result; result DecimalToBinary(int number){ result r; while(number!=0){ rb[n++] = number%2; number/=2; } return r; } // usage example result r = DecimalToBinary(42); 

如果你使用malloc()选项,请不要忘记在完成后释放()返回的数据,否则它会挂起。 这称为内存泄漏。 在更复杂的程序中,它可能导致严重的问题。

注意:顺便说一句,如果您的数字大于1023(10位二进制数字),您将超出arrays。 您可能还希望在存储10位数字后明确停止,或者传递数组的大小,或者首先计算所需的大小并分配那么多空间。 此外,如果您的号码为负数,您将获得一些奇怪的结果,您可能希望使用number&1而不是number%2

注2:如其他地方所述,你应该使n local,或者至少在每次调用函数时将它重新激活为0,否则它将只是累积,最终你将超过数组的末尾。

您返回指向本地数组的指针。 该本地数组位于堆栈上,当函数返回时,数组超出范围,并且在调用下一个函数时将重用堆栈内存。 这意味着指针现在将指向其他一些数据,而不是原始数组。

有两种解决方案:

  1. 调用 DecimalToBinary的函数中声明数组并将其作为参数传递。
  2. 在堆上动态创建数组(例如使用malloc )并返回该指针。

方法2的问题是如果不free返回的指针,它可能会创建内存泄漏。


正如Craig所指出的,还有第三种解决方案,即在函数内部使数组static化。 然而,在这种情况下,它带来了比我最初列出的两个解决方案更多的问题,这就是我没有列出它的原因。

正如Uchia Itachi所指出的那样,代码还存在另一个严重的问题,那就是数组被全局变量索引。 如果使用太大的数字或多次调用DecimalToBinary函数,则此全局索引变量对于数组将变大,并且将超出该数组的范围。

解除引用指向超出范围的数组的指针和索引超出范围的问题都会导致未定义的行为 。 如果你幸运的话,未定义的行为会导致打印出错误的结果。 如果你运气不好会导致程序崩溃。

int[10]int * ; 不仅前者是在堆栈上创建的,它还是一个完全不同的类型。 你需要像这样创建一个实际的int *

 int *a = malloc (10 * sizeof (int)); 

当然,使用后别忘了free()吧!

您还可以做什么以及在C中通常做的是创建调用它的数组并向该函数提供指向该数组的指针,这种方式当数组位于调用它的函数的堆栈上而不是function自我。 我们还必须为该函数指定数组的大小,因为函数无法知道指针指向的元素数量

 void DecimalToBinary( int number, int* output, unsigned size ) { /*adapt this to your liking*/ int i; for ( i = 0; i < size && number != 0; i++) { output[i] = number%2; number/2; } } 

在你的主要function,你会这样称呼它:

 int array[10]; DecimalToBinary( 5, array, sizeof(array)/sizeof(array[0])); 

现在数组的结果与您的示例中的结果相同。

你的代码中的问题就在这里..

 int * DecimalToBinary(int number){ int a[10]; while(number!=0){ a[n++] = number%2; number/=2; } return a; 

}

数组范围仅在此函数之前。 一旦此函数终止,将释放为此数组分配的内存,您需要使用动态内存分配或使数组成为全局内存。

这是正确的程序:

 #include  int n = 0; int a[10] = {0}; int* DecimalToBinary(int number){ n = 0; while(number!=0){ a[n++] = number%2; number = number/2; } return a; } int main(){ int *d1; int *d2; int i; d1 = DecimalToBinary(5); for(i = n-1;i>=0;i--) printf(" %d",d1[i]); printf("\n"); d2 = DecimalToBinary(10); for(i = n-1;i>=0;i--) printf(" %d",d2[i]); printf("\n"); }