在c中为2D数组分配内存时的分段失败

时间:2015-04-04 23:27:01

标签: c memory memory-management multidimensional-array malloc

我有一个函数,它返回字母表中可能的所有字母组合,并在长度为LENTH_MAX的字中重复。该函数在2D数组调用中返回这些组合' arr'。

因为计算数组总数是一件痛苦的事,因为你需要计算阶乘数[(n + r - 1)!/ r!(n - 1)!我决定越来越多地为阵列中的阵列重新分配内存。根据需要。

我设置了一个名为capacity的变量,用于确定' arr'的初始大小。和一个名为CAP_INCR的常量,它指定除了已分配的内存之外将重新分配内存的数组的数量。如果我将CAP_INCR设置为1,则程序编译好,这样每次找到新组合时,为该数组分配新内存,程序将使用Segmentation fault:11消息,如果我将CAP_INCR设置为100,如果正确完成但是输出是错误的,第一个组合' aa a'重复两次,最后一次组合' z z z'是使命。

我真的很感激一些帮助。我是其他语言的一个不错的程序员,但我只是从C开始。

代码是:

#include <stdio.h> 
#include <stdlib.h> 

const unsigned short LENGTH_MAX = 3; 

const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; 

#define CAP_INCR  1 /* memory increases */ 

unsigned char* combinations(unsigned char n, unsigned char r) 
{ 
    // n  length of alphabet 
    // r  length of figures 
    unsigned int  set_counter = 0;        //counting generated sequences 

    unsigned char *vector = NULL;   //where the current figure is stored 
    unsigned char *arrTemp = NULL;    // Temporary pointer store 

    unsigned int capacity = 100; // count current size of arr 
    unsigned char *arr = (unsigned char *)malloc(capacity * r * sizeof(unsigned char)); // multidimentional array 


    vector = (unsigned char *)malloc(sizeof(unsigned char) * r); 


    if(vector == NULL || arr == NULL) 
    { 
        fprintf(stderr, "error: insufficient memory\n"); 
        exit(EXIT_FAILURE); 
    } 


    //initialize: vector[0, ..., r - 1] are 0, ..., r - 1 
    for(int l = 0; l < r; l++) //for(int l = 0; l < r; l++) // no repetition 
        vector[l] = 0; 

    //generate all successors 
    while(1) 
    { 
        set_counter++; 

        // check is arr current capacity is enough 
        if(set_counter > capacity) 
        { // We need more memory 
            capacity += CAP_INCR; 
            arrTemp = (unsigned char *)realloc(arr, capacity * r * sizeof(unsigned char)); 
            if(!arrTemp) 
            { 
                printf("Unfortunately memory reallocation failed.\n"); 
                free(arr); 
                arr = NULL; 
                exit(0); 
            } 
            arr = arrTemp; 
        } 

        for(int x = 0; x < r; x++) { // assign a new combination to arr 
            //printf("%c ", alphabet[vector[x]]); 
            *(arr + set_counter*r + x) = vector[x]; 
        } 

        //printf("(%u)\n", set_counter); 

        int j; //index 

        //easy case, increase rightmost element 
        if(vector[r - 1] < n - 1) 
        { 
            vector[r - 1]++; 
            continue; 
        } 

        //find rightmost element to increase 
        for(j = r - 2; j >= 0; j--) { 
            if(vector[j] != n - 1) { 
                break; 
            } 
        } 

        //terminate if vector[0] == n - r 
        if(j < 0) 
            break; 

        //increase 
        vector[j]++; 

        //set right-hand elements 
        for(j += 1; j < r; j++) 
            vector[j] = vector[j - 1]; 

    } 

    return arr; 
} 



int main() { 

    unsigned char* arr = combinations(sizeof(alphabet)-1, LENGTH_MAX); 

    int c=0; 
    for (int i = 0; i < 3276; i++) // 3276 is the total number of combinations 
    { 
         for (int j = 0; j < 3; j++) 
         { 
             printf("%c ", alphabet[*(arr + i*3 + j)]); 
         } 
         printf("count: %d\n",++c); 
    } 


    return 0; 
} 

0 个答案:

没有答案