在C

时间:2016-06-09 10:59:54

标签: c arrays string segmentation-fault

下面是函数 fast_integer_output ,它将 input_integer 从base 2转换为 output_base

my_str* fast_integer_output(bigint* input_integer, int output_base)
{
    bigint** integer_to_binary_array = create_integer_to_binary_array();
    bigint* base = integer_to_binary_array[output_base];
    my_str* result = 0;

    if(less_than(input_integer, base))
    {
        char* p_char = (char*) get_memory(sizeof(char));
        p_char[0] = int_to_char(*(input_integer->number));

        result = create_string(p_char, 1);
    }
    else
    {
        long k = find_k(input_integer, base);
        bigint* base_to_k = power(base, k);

        bigint* quotient;
        bigint* remainder;

        divide(input_integer, base_to_k, &quotient, &remainder);
        delete_bigint(&base_to_k);

        my_str* low = fast_integer_output(remainder, output_base);
        delete_bigint(&remainder);

        my_str* high = fast_integer_output(quotient, output_base);
        delete_bigint(&quotient);

        result = concatenate(low,  k - low->length, high);

        delete_string(&low);
        delete_string(&high);
    }

    release_integer_to_binary_array(integer_to_binary_array);
    return result;
}

以下是 bigint my_str 结构和 create_string 函数(bitarray只是指向long的指针)

my_str* create_string(char* c_str, long length)
{
    my_str* str = (my_str*) get_memory(sizeof(my_str));
    str->c_str = c_str;
    str->length = length;
}

typedef struct
{
    char*   c_str;
    long    length;  // logical
} my_str;

typedef struct
{
    bitarray*   number;
    long        length;  // logical
    long        size;    // physical
} bigint;

此功能负责内存管理。现在他们只是将函数包装到 free malloc ,但是如果操作起来很慢,我想实现某种内存池。

void init_memory(void* memory, size_t size)
{
    unsigned char* tmp = (unsigned char*) memory;
    unsigned char c = 0;

    while (size > 0)
    {
        *tmp = c;
        tmp++;
        size--;
    }
}

void* get_memory(size_t size)
{
    void* memory = malloc(size);
    init_memory(memory, size);
    return memory;
}

void release_memory(void** memory)
{
    free(*memory);
    *memory = 0;
}

问题是一切都在调试配置上运行良好,但在发布配置中,函数 fast_integer_output 在该行上失败:

result = concatenate(low,  k - low->length, high);

问题在于

my_str* low = fast_integer_output(remainder, output_base);

从这段代码中返回

if(less_than(input_integer, base))
{
    char* p_char = (char*) get_memory(sizeof(char));
    p_char[0] = int_to_char(*(input_integer->number));

    result = create_string(p_char, 1);
}

返回垃圾,因此在分段错误时失败。

我对此代码有同样的问题:

QString buffer; // function parameter in real code
instance_data_t data = {(unsigned char*) buffer.toStdString().c_str(), 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, cur_state};

但我设法通过将其更改为以下内容来实现它:

unsigned char c_buffer[1024];
memset(c_buffer, '\0', sizeof(c_buffer));
strcpy((char *) c_buffer, buffer.toStdString().c_str());

instance_data_t data = {c_buffer, 0, 0, 0, 0, 0, 0, {0, 0}, {0, 0}, cur_state};

重要提示是我不能使用除 write read ,malloc和 free 之外的任何其他功能(所以没有strcpy,上面的代码是从测试我不会提供)

这不是作业,而是作业的任务(我想得到)。

我已经搜索并阅读了大约15-20个问题,所以我不会全部列出,但问题是,如果问题不是很具体,那么分段错误不是因为字符串操作和如果是,则主要是因为索引越界。

1 个答案:

答案 0 :(得分:0)

您分配的字符串不为空(' \ 0')已终止。

我会这样做:

  char* p_char = (char*) get_memory(sizeof(char) * 2);

  p_char[0] = int_to_char(*(input_integer->number));
  p_char[1] = 0;

  result = create_string(p_char, 1);

正如EOF指出的那样(见评论), create_string函数为无return语句。 因此,确实返回了垃圾。

my_str* create_string(char* c_str, long length)
{
    my_str* str = (my_str*) get_memory(sizeof(my_str));
    str->c_str = c_str;
    str->length = length;
    return str;
}