无法返回int数组

时间:2013-08-06 07:32:33

标签: c arrays

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

#include <stdio.h>
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]);

}

6 个答案:

答案 0 :(得分:8)

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

有两种解决方案:

  1. 在函数中调用 DecimalToBinary声明数组并将其作为参数传递。
  2. 在堆上动态创建数组(例如,使用malloc)并返回该指针。
  3. 方法2的问题在于,如果你没有free返回的指针,它可能会造成内存泄漏。


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

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

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

答案 1 :(得分:3)

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

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

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){
        r.b[n++] = number%2;
        number/=2;
    }
    return r;
}

// usage example
result r = DecimalToBinary(42);

如果你选择了malloc()选项,那么当你完成它时,不要忘记释放()返回的数据,否则它会一直存在。这称为内存泄漏。在更复杂的程序中,它可能导致严重的问题。

注意:顺便说一句,如果您的数字大于1023(10位二进制数字),您将超出阵列。您可能还希望在存储10位数字后显式停止,或者传入数组的大小,或者首先计算所需的大小并分配那么多空间。此外,如果您的号码为否定,您会收到一些奇怪的结果,您可能希望使用number&1代替number%2

注意2:如其他地方所述,你应该n本地,或者至少在每次调用函数时将它重新激活为0,否则它会累积并最终你会超过结束数组。

答案 2 :(得分:1)

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

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

当然,使用后不要忘记free()

答案 3 :(得分:0)

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

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;
    }
}

在你的主要功能中,你会这样称呼它:

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

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

答案 4 :(得分:0)

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

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

}

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

答案 5 :(得分:-1)

这是正确的程序:

#include <stdio.h>
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");
}