在C中重新分配字符串数组和分配新字符串

时间:2015-02-06 14:20:45

标签: c arrays string

有人知道这段代码有什么问题吗?我想重新分配一个char**数组,然后为新字符串(char*)分配空间。

void reallocate(char*** array, int* p_capacity) {
    int i;
    int capacityBefore;
    char **pp_tmp;
    if ((pp_tmp = (char**) realloc(*array, (2 * (*p_capacity) * sizeof (char*)))) == NULL) { 
        printf("Nedostatek pameti.\n");
        free((void*) pp_tmp);
        exit(1);
    }

    capacityBefore = *p_capacity;
    *p_capacity *= 2;

    for (i = capacityBefore; i < *p_capacity; ++i) {
        if ((pp_tmp[i] = (char*) malloc(LENGTH * sizeof (char))) == NULL) { 
            printf("Nedostatek pameti.\n");
            exit(1);
        }
    }
    *array = pp_tmp;
}

1 个答案:

答案 0 :(得分:0)

我接受了您的代码并对其进行了非常温和的修改(使用size_t代替int作为大小参数,并报告标准错误而非标准输出的错误),并将其放入像这样的测试工具:

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

enum { LENGTH = 32 };

static
void reallocate(char ***array, size_t *p_capacity)
{
    size_t i;
    size_t capacityBefore;
    char **pp_tmp;
    if ((pp_tmp = (char **) realloc(*array, (2 * (*p_capacity) * sizeof(char *)))) == NULL)
    {
        fprintf(stderr, "Nedostatek pameti.\n");
        free((void *) pp_tmp);
        exit(1);
    }

    capacityBefore = *p_capacity;
    *p_capacity *= 2;

    for (i = capacityBefore; i < *p_capacity; ++i)
    {
        if ((pp_tmp[i] = (char *) malloc(LENGTH * sizeof(char))) == NULL)
        {
            fprintf(stderr, "Nedostatek pameti.\n");
            exit(1);
        }
    }
    *array = pp_tmp;
}

int main(void)
{
    char **array = malloc(1 * sizeof(*array));
    if (array == NULL)
    {
        fprintf(stderr, "Nedostatek pameti.\n");
        exit(1);
    }
    array[0] = malloc(LENGTH * sizeof(*array[0]));
    if (array[0] == NULL)
    {
        fprintf(stderr, "Nedostatek pameti.\n");
        exit(1);
    }
    strcpy(array[0], "Initial string");
    size_t size = 1;

    for (size_t i = 0; i < 4; i++)
    {
        size_t old_size = size;
        reallocate(&array, &size);
        for (size_t j = old_size; j < size; j++)
            snprintf(array[j], LENGTH, "Additional string %zu", j);
    }

    for (size_t i = 0; i < size; i++)
        printf("%2zu: %s\n", i, array[i]);

    return 0;
}

valgrind下运行它会给它一个干净的健康状况 - 除了泄漏所有内存,因为它不会尝试释放任何已分配的内存。

但请注意,main()中有手动分配步骤以便进行分配。如果将零大小传递给函数,则零两次仍然为零,因此没有任何变化。我对您的问题的最佳猜测是您拥有的初始化代码(但未显示)不安全,或者您将数组大小设置为零。下一个最好的猜测是,您将比LENGTH更长的字符串复制到数据中,但我认为这不太可能。

示例输出:

 0: Initial string
 1: Additional string 1
 2: Additional string 2
 3: Additional string 3
 4: Additional string 4
 5: Additional string 5
 6: Additional string 6
 7: Additional string 7
 8: Additional string 8
 9: Additional string 9
10: Additional string 10
11: Additional string 11
12: Additional string 12
13: Additional string 13
14: Additional string 14
15: Additional string 15

请记住,您应该创建并发布MCVE(Minimal, Complete, Verifiable Example)或SSCCE(Short, Self-Contained, Correct Example) - 两个名称和相同基本想法的链接 - 以便人们可以更轻松地了解您所看到的内容作为你的问题。

使用GCC 4.9.1和Valgrind 3.10.0在Mac OS X 10.9.5 Mavericks上进行测试。