c - 结构内部数组的声明有时会失败

标签 c arrays struct segmentation-fault

是什么导致以下代码在某些 Linux/gcc 环境中失败?我声明一个结构,然后创建该结构的“实例”。问题在于数组,它应该保存单独的字符串并且可以调整大小。详情:

typedef struct {
    char (*pointer)[256];
    int used;
    int size;
} Array;

Array *createArray(int start_size) {
    Array *array = malloc(sizeof( *array));
    array->used = 0;
    array->size = start_size;
    array->pointer = malloc(start_size * sizeof *array->pointer); // <--- here
    return array;
}

使用未初始化值的行标记为 <--下面( strcpy )。 parse功能append使用 append 到数组功能。

void append(Array *array, char* elem) {
    if (array->used >= array->size) {
        // expand table
        array->pointer = realloc(array->pointer, array->size * 2 * sizeof *array->pointer);
        array->size *= 2;
    }
    // append new arg
    strcpy(array->pointer[array->used] , elem); // <-- here
    array->used++;
}

Array *parse(char* command) {
    // split command by space and store each arg in array
    char *args_str;
    Array *args_list = createArray(DEFAULT_SIZE); // expandable array holding arguments
    args_str = strtok(command, " ");
    append(args_list, args_str);
    args_str = strtok(NULL, " ");
}

Valgrind 显示,上面标有 <--- here 的行有一个错误由于使用了未初始化的值,但代码在 Valgrind 内以及以下位置上运行良好:

CentOS Linux release 7.4.1708 (Core) 3.10.0-693.11.6.el7.x86_64, gcc version 4.8.5 20150623 (Red Hat 4.8.5-16)
Ubuntu 16.04.3 LTS 4.4.0-112-generic, gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.6)

但是失败了:

Linux kali 4.13.0-kali1-amd64, gcc version 7.2.0 (Debian 7.2.0-14)

throw SEGFAULT 11第一次输入程序后,即编译过程之后,它在每个环境上都可以正常编译。

最佳答案

根据 Pablo 的评论,需要修复 parse 逻辑并改进 realloc!如前所述,当 mallocrealloc 返回时检查 NULL

这是一个供您进一步改进的 MCVE:

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

#define DEFAULT_SIZE 256

typedef struct {
    char (*pointer)[256];
    int used;
    int size;
} Array;

Array *createArray(int start_size) {
    Array *array = malloc(sizeof(*array));
    array->used = 0;
    array->size = start_size;
    array->pointer = malloc(start_size * sizeof * array->pointer); // 
    return array;
}

void append(Array *array, char* elem) {
    if (array->used >= array->size) {
        // expand table
        array->pointer = realloc(array->pointer, array->size * 2 * sizeof * array->pointer);
        array->size *= 2;
    }
    // append new arg
    strcpy(array->pointer[array->used] , elem); // <-- here
    array->used++;
}


Array *parse(char* command) {
    // split command by space and store each arg in array
    char *args_str;
    Array *args_list = createArray(DEFAULT_SIZE); // expandable array holding arguments

    args_str = strtok(command, " ");

    append(args_list, args_str);

    args_str = strtok(NULL, " ");

    append(args_list, args_str);

    return(args_list);
}

int main(void)
{
    char str[] = { '1', '2', '3', ' ', '5', '6', '7', ' ', 0 };

    Array *p = parse(str);

    printf("%s\n",p->pointer[0]);
    printf("%s\n",p->pointer[1]);

    return 0;
}

输出:

123
567

关于c - 结构内部数组的声明有时会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48875683/

相关文章:

开罗图书馆 : produce a png file with white background

硬币找零算法C

java - 如何生成一个介于 -1 和 1 之间的随机数?

c - 当函数中的值发生变化时,指针不反射(reflect)变化

c - 将创建多少进程?

arrays - 与 AD 中的职位列表匹配的用户列表

Java,计算随机数并保存的程序

struct - 如何从函数访问结构的实例字段?

c - 如何查找 C 结构 (struct sockaddr_in) 的手册页?

c - 如何正确地将包含 int 数组的结构分配给结构数组?