c 程序的工作方式不同,但我没有改变它

问题描述 投票:0回答:1

我必须在c中实现动态数组。这是它的结构:

typedef void (*PrintArrayElement)(const void* element);

typedef struct {
    size_t size;
    size_t capacity;
    void** array;
    PrintArrayElement printElement;  // Callback
} dynamic_array;

我已经实现了向数组添加元素的功能:

void arrayAddItem(dynamic_array* container, void* item)
{
    if (container->size == container->capacity)
    {
        void** temp = container->array;
        container->capacity <<= 1;
        container->array = (void **)realloc(container->array, container->capacity * sizeof(void*));
        if (!container->array)
        {
            printf("Out of Memory\n");
            container->array = temp;
            return;
        }
    }
    container->array[container->size] = strdup(item);
    container->size++;
}

我还有在字符串中查找单词索引的功能:

dynamic_array* findWord(char str[], char keyword[])
{
    dynamic_array* indexes;
    arrayInit(&indexes, 16, printInt);
    int i = 0;
    int start = 0;
    int end = 0;
    size_t len = strlen(str);
    while (i < len) {
        while (i < len && !isalpha(str[i]))
        {
            i++;
        }
        if (isalpha(str[i]))
        {
            start = i;
            while (i < len && isalpha(str[i]))
            {
                i++;
            }
            end = i;
            char* word = (char*)malloc(end - start + 1);
            strncpy(word, &str[start], end - start);
            word[end - start] = '\0';
            if(strcmp(word, keyword) == 0)
            {
                printf("%d\n", start);
                arrayAddItem(indexes, &start);
            }
            free(word);
        }
    }
    return indexes;
}

所以我写了

dynamic_array* test_find_array1 = findWord("hello, world, hello", "hello");
并等待有两个元素的dynamic_array:0和14,但我有一个带有指针的dynamic_array。而主要的问题是,有时我有正确的答案,但我没有重写代码。为什么会发生?

我尝试重写 findWord 函数和 arrayAddItem 但它仍然是随机的。我不知道出了什么问题。让我知道我是否应该从项目中添加一些其他功能的代码。

c pointers data-structures void void-pointers
1个回答
0
投票
  1. 您应该提供一个程序而不是不完整的代码片段。您缺少标头、

    arrayInit()
    printInt()
    main()
    的实现。另外你的程序会泄漏内存。我添加了示例实现供您测试代码。

  2. printElement
    未使用,因此您应该从此处提供的最小程序中删除它。

  3. 如果
  4. arrayAddItem

    初始化为 0,

    capacity
    将失败。您期望分配内存,并且
    malloc(0)
    是实现定义的,并且可能为 NULL,如果
    realloc()
    失败,现在会与检查发生冲突。我添加了一个检查,如果是 0,则默认为
    capacity = 1

  5. arrayAddItem()
    使用
    strdup()
    来复制
    item
    ,这意味着它采用一个字符串。在
    findWord()
    中,您传入
    int
    ,因此这很可能会出现段错误。更改 API 以期望调用者提供数据的副本,并且调用者还负责释放所述数据(为了对称)。

  6. 如果
  7. arrayAddItem()

    失败(新容量而不是旧容量),

    container->capacity
    将返回无效的
    realloc()
    。我更新了代码以使用变量。

  8. arrayAddItem()
    错误处理策略不一致。您忽略
    strdup()
    失败的可能性,并在
    realloc()
    失败时返回损坏的数据。您不会检查
    arrayInit()
    是否失败,因此我认为您不会返回任何内容。现在在失败时编码
    exit(1)
    。 API 需要更改才能避免这些错误,但如果你内存不足,你可能无论如何都会退出。

  9. findWord()
    最小化变量范围并避免未使用的
    start = 0
    end = 0

  10. findWord()
    尚不清楚您是否要存储索引数组或字符串数组,因此此处使用字符串(
    word
    )。如果你不想存储它,那么花费所有精力来创建关键字的副本有点愚蠢,所以这就是我所做的(并且只有免费的
    word
    ,如果它不是关键字)。如果你想存储索引,只需执行
    strncmp()
    并检查你找到的字符串的长度是否与关键字的长度相同。然后为
    int
    分配空间并将其传递给
    arrayAddItem()

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

typedef struct {
    size_t size;
    size_t capacity;
    void** array;
} dynamic_array;

void arrayInit(dynamic_array **container, size_t capacity)
{
    *container = malloc(sizeof **container);
    if(!*container)
    {
        printf("malloc failed\n");
        exit(1);
    }
    (*container)->size = 0;
    (*container)->capacity = capacity;
    (*container)->array = capacity ? malloc(sizeof *(*container)->array * capacity) : NULL;
    if(capacity && !(*container)->array)
    {
        printf("malloc of array failed\n");
        exit(1);
    }
}

void arrayFree(dynamic_array *container) {
    if(!container) return;
    free(container->array);
    free(container);
}

void arrayAddItem(dynamic_array* container, void* item) {
    if (container->size == container->capacity)
    {
        size_t new_capacity = container->capacity ? container->capacity * 2 : 1;
        void **new_array = realloc(container->array, sizeof *(container->array) * new_capacity);
        if(!new_array)
        {
            printf("malloc failed\n");
            exit(1);
        }
        container->capacity = new_capacity;
        container->array = new_array;
    }
    container->array[container->size] = item;
    container->size++;
}

dynamic_array* findWord(char str[], char keyword[]) {
    dynamic_array* indexes;
    arrayInit(&indexes, 0);
    int i = 0;
    size_t len = strlen(str);
    while (i < len) {
        while (i < len && !isalpha(str[i]))
            i++;
        if (isalpha(str[i]))
        {
            int start = i;
            while (i < len && isalpha(str[i]))
            {
                i++;
            }
            int end = i;
            char* word = malloc(end - start + 1);
            if(!word)
            {
                printf("malloc failed\n");
                exit(1);
            }
            strncpy(word, &str[start], end - start);
            word[end - start] = '\0';
            if(strcmp(word, keyword) == 0)
            {
                printf("%d\n", start);
                arrayAddItem(indexes, word);
            } else
                free(word);
        }
    }
    return indexes;
}

int main(void)
{
    dynamic_array *container = findWord("hello world", "hello");
    for(size_t i = 0; i < container->size; i++)
    {
        printf("%s\n", (char *) container->array[i]);
        free(container->array[i]);
    }
    arrayFree(container);
}
© www.soinside.com 2019 - 2024. All rights reserved.