首页 > 解决方案 > 在 C 中的堆栈和/或堆上实现用户定义的数组

问题描述

在学习 C 语言编程时,我试图了解堆栈之间的区别。
为此,我尝试实现二进制搜索。我想从用户那里获取二进制搜索的输入数据集。为了做到这一点,我希望用户能够定义数据集的大小(在本例中为数组)。一旦获得数组的大小,我就初始化数组,然后要求用户用值填充它。

我对堆栈的(可能是错误的)理解是,如果在编译时知道数组的大小,则可以在堆栈上初始化该数组。因此,我尝试了以下方法来实现堆栈上的用户输入(并且它“有效”):

void getUserInput(int sizeArray, int inputArray[], int userIn[]){
    /* get input data set and the element to be searched for from user */

    printf("Enter data elements seperated by a comma, e.g. 1,2,3. Press Enter at the end. Do not enter more than %d numbers: \n", sizeArray);
    for (int i = 0; i < sizeArray; i++){
        scanf("%d, ", &inputArray[i]);
    }
    printf("\nEnter the number to be searched for: \n");
    scanf("%d", &userIn[1]);

    printf("\nFor iterative implementation, enter 0. For recursive implementation, enter 1 :\n");
    scanf("%d", &userIn[0]);
}

int main(int arg, char **argv){
   int sizeArray;
   int userIn[2];                                                  // userIn[1]: element to be searched for; userIn[0]: iterative or recursive implementations
   printf("Enter size of input array: \n");
   scanf("%d", &sizeArray);
        
   int inputArray[sizeArray];
        
   getUserInput(sizeArray, inputArray, userIn);

// more code ...

}

对于堆上的实现,我尝试使用动态内存分配(它也“有效”):

int main(int arg, char **argv) {
    int sizeArray;
    int userIn[2];                                                  // userIn[1]: element to be searched for; userIn[0]: iterative or recursive implementations
    printf("Enter size of input array: \n");
    scanf("%d", &sizeArray);

    int *inputArray;

    inputArray = (int*) malloc(sizeArray * sizeof(int));
    if(inputArray == NULL) {
        printf("\n\nError! Memory not allocated, enter size of array again:\n");
        scanf("%d", &sizeArray);
        inputArray = (int*) malloc(sizeArray * sizeof(int));
    }
    getUserInput(sizeArray, inputArray, userIn);

// more code...
    free(inputArray)                                               // free memory allocated by malloc on the heap
}

现在,我想将这两种方法合并到一个文件中,所以我创建了一个开关来在堆栈和堆实现之间切换,如下所示:

int main(int arg, char **argv) {
    /* Obtain input */
    int stackHeap;                                                      // 0 = implementation on stack; 1 = implementation on heap
    printf("Implementation on stack or heap? Enter 0 for stack, 1 for heap: \n");
    scanf("%d", &stackHeap);

    int sizeArray;
    int userIn[2];                                                  // userIn[1]: element to be searched for; userIn[0]: iterative or recursive implementations
    printf("Enter size of input array: \n");
    scanf("%d", &sizeArray);
    int *inputArray;

    if (stackHeap == 0) {
        inputArray =  &inputArray[sizeArray];    
        printf("input array = %p\n", inputArray);
    } else {
        inputArray = (int*) malloc(sizeArray * sizeof(int));
        printf("input array = %p\n", inputArray);
        if(inputArray == NULL) {
            printf("\n\nError! Memory not allocated, enter size of array again:\n");
            scanf("%d", &sizeArray);
            inputArray = (int*) malloc(sizeArray * sizeof(int));
        }
    }

    getUserInput(sizeArray, inputArray, userIn);
// more code...
}

目前堆栈方法不起作用。我尝试在 if 语句中初始化 inputArray,而不是 inputArray = &inputArray[sizeArray]。然而这是不允许的,因为它只在 if 语句的范围内有效。我想我对如何使用指针 *inputArray 来初始化堆栈上的数组感到困惑。

我一直在阅读 C 中的指针和数组,这就是为什么我认为实现它会很有趣。我非常感谢您的任何反馈(很高兴我犯的任何基本错误 - 我对这个主题很陌生)。

非常感谢你!

标签: arrayscpointersstackheap-memory

解决方案


您的程序仅使用堆栈分配或仅使用堆分配都很好。堆栈分配的唯一潜在问题是,如果数组太大(即几 MB),它可能会溢出堆栈,而堆有更高的限制。

组合程序的问题在于这没有意义:

inputArray =  &inputArray[sizeArray]; 

使用数组索引运算符实际上涉及取消引用指针,并且此时inputArray并不指向任何地方。

您需要选择一个或另一个,数组或指向动态分配数组开头的指针。


推荐阅读