Malloc堆栈溢出

时间:2017-04-17 17:11:44

标签: c

下面代码的人工作正常,直到size = 100000.但是它在size = 200000之后给出了堆栈溢出错误。 我该如何解决这个问题? 有没有办法优化它?

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define SIZE 500000
// HELPER ARRAY FUNCTIONS
void check(int *arr)
{
    int i = 0;
    for (i = 0; i < SIZE - 1; i++)
    {
        if (arr[i]>arr[i + 1])
        {
            printf("Not sorted.\n");
            return;
        }
    }
    printf("Sorted.\n");
}
void fill_array(int *arr)
{
    int i = 0;
    for (i = 0; i < SIZE; i++)
        arr[i] =rand()%100;
}
void print_array(int *arr)
{
    int i;
    for (i = 0; i < SIZE; i++)
        printf("%d ", arr[i]);
    printf("\n");
}
// NODE STRUCT
typedef struct BST_NODE
{
    struct BST_NODE *left, *right;
    int data;
}node;
// TREE FUNCTIONS
node* generate_node(int *value)
{
    node *n = (node*)malloc(sizeof(node));
    n->left = NULL;
    n->right = NULL;
    n->data = *value;
    return n;
}
node* insert_node(node *n, int *value)
{
    if (n == NULL)
        return generate_node(value);
    if (*value < n->data)
        n->left = insert_node(n->left, value);
    else
        n->right = insert_node(n->right, value);
    return n;
}
node* construct_BST(int *arr, node* n)
{
    int i;
    n = NULL;
    for (i = 0; i < SIZE; i++)
        n = insert_node(n, &arr[i]);
    return n;
}
int s = 0;
void LVR(int *arr, node* n)
{
    if (n != NULL)
    {
        LVR(arr, n->left);
        arr[s] = n->data;
        s++;
        LVR(arr, n->right);
    }
}
void tree_sort(int *arr)
{
    node *root = (node*)malloc(sizeof(node));
    root = construct_BST(arr, root);
    LVR(arr, root);
}
// DRIVER PROGRAM
int main()
{
    int *Array = (int*)malloc(sizeof(int)*SIZE);
    fill_array(Array);
    tree_sort(Array);
    print_array(Array);
    check(Array);
    free(Array);
    getchar();
    return 0;
}

以下部分给出了错误:

node* generate_node(int *value)
{
    node *n = (node*)malloc(sizeof(node));
    n->left = NULL;
    n->right = NULL;
    n->data = *value;
    return n;
}

2 个答案:

答案 0 :(得分:1)

如果您发现堆栈溢出,则意味着您的函数调用堆栈变得太深。如果树最终不平衡,那么在构建二叉搜索树时就会发生这种情况。

最好的情况是,您的树高为O(log n),最差情况为O(n)。如果您按排序顺序将项目放入树中,您的二叉树将退化为链接列表,并且您将遇到最坏的情况。

对于此特定示例,您将生成0到99之间的随机数。如果增加数字范围,则可能会获得更多随机化结果。因此,请使用rand()%100之类的内容,而不是使用rand()%10000。这可能有助于保持树的高度。

在不相关的说明中,您有内存泄漏。首先,为树的根分配的初始节点会被覆盖,因此您不需要它。其次,你从不打扰释放树形结构。

您可以按照以下方式处理这些问题:

void free_tree(node *root)
{
    if (root) {
        free_tree(root->left);
        free_tree(root->right);
        free(root);
    }
}

void tree_sort(int *arr)
{
    node *root = NULL
    root = construct_BST(arr, root);
    LVR(arr, root);
    free_tree(root);
}

答案 1 :(得分:1)

正如其他人已经指出的那样,问题是在最坏的情况下树的深度将为SIZE

对于代码,由于要保留的值是小于100的值,因此可以通过不为相同值创建新节点来抑制树的深度。

如果相同的值更改计数如下。

#include <stdio.h>
#include <stdlib.h> //stdlib.h include malloc and free

#define SIZE 500000


typedef struct BST_NODE {
    struct BST_NODE *left, *right;
    int data;
    int count;//Add for count
} node;

node* generate_node(int value){//just use int
    node *n = (node*)malloc(sizeof(node));//C does not need to cast from  void *.
    n->right = n->left = NULL;
    n->data = value;
    n->count = 1;//set 1 at first time
    return n;
}

node* insert_node(node *n, int value){
    if(n == NULL)
        return generate_node(value);
    if(value < n->data)
        n->left = insert_node(n->left, value);
    else if (value > n->data)
        n->right = insert_node(n->right, value);
    else
        n->count++;//Add count up
    return n;
}

node* construct_BST(int *arr){//no need node *n as argument 
    int i;
    node *n = NULL;
    for (i = 0; i < SIZE; i++)
        n = insert_node(n, arr[i]);
    return n;
}

int s = 0;
void LVR(int *arr, node *n){
    if (n != NULL){
        int i;
        LVR(arr, n->left);
        for(i = 0; i < n->count; ++i)
            arr[s++] = n->data;//Repeat as many times as count
        LVR(arr, n->right);
    }
}

void tree_free(node *n){
    if(n){
        tree_free(n->left);
        tree_free(n->right);
        free(n);
    }
}

void tree_sort(int *arr){
    node *root = construct_BST(arr);
    s = 0;//Necessary for different calls
    LVR(arr, root);
    tree_free(root);//release tree
}