c - malloc/结构指针数组段错误

标签 c struct segmentation-fault malloc

我有下面的代码,包括 main 中调用的函数和其他函数是正确的。但是当我试图 malloc words[counter]->input_str ,我总是遇到段错误。我不知道该怎么办。

    struct copy {
        char *input_str;
        char *create_word;
    };

    int main(int argc, char *argv[]) {
        static struct copy *words[ARRAY_SIZE];
        char format_str[20];
        char word_str[STR_SIZE];
        int how_many;
        int counter = 0;
        char answer;

        do{

            sprintf(format_str," %%%ds",STR_SIZE - 1);
            printf("Enter string: ");
            scanf(format_str,word_str);


            words[counter]->input_str = (char *)malloc((strlen(word_str) + 1)*sizeof(char));
            if(words[counter]->input_str == NULL) {
                printf("memory problem\n");
                exit(-1);
            }
            words[counter]->input_str = word_str;

            printf("Enter integer: ");
            scanf(" %d",&how_many);

            words[counter]->create_word = duplicate(word_str,how_many);
            counter++;
            if(words[counter - 1] == NULL) {
                printf("error\n");
                exit(-1);
            }
            print(words,counter);

            do{
                printf("More (y/n)? ");
                scanf(" %c",&answer);
            }while(answer != 'y' && answer != 'n');


        }while(counter < ARRAY_SIZE && answer == 'y');

        clean(words,counter);

        return(0);
    }

最佳答案

这里有两个版本的代码,一个使用 main() 顶部的 struct copy *words[ARRAY_SIZE];,另一个使用 struct复制单词[ARRAY_SIZE];(因此会减少内存分配)。

指针数组

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

struct copy
{
    char *input_str;
    char *create_word;
};

enum { ARRAY_SIZE = 20, STR_SIZE = 30 };

extern char *duplicate(const char *str, int number);
extern void print(struct copy **words, int number);
extern void clean(struct copy **words, int number);

int main(void)
{
    struct copy *words[ARRAY_SIZE];
    char format_str[20];
    char word_str[STR_SIZE];
    int how_many;
    int counter = 0;
    char answer;
    sprintf(format_str, " %%%ds", STR_SIZE - 1);

    do
    {
        printf("Enter string: ");
        if (scanf(format_str, word_str) != 1)
            break;

        printf("Enter integer: ");
        if (scanf(" %d", &how_many) != 1 || how_many < 0 || how_many > 999)
            break;

        words[counter] = malloc(sizeof(*words[counter]));
        words[counter]->input_str = (char *)malloc((strlen(word_str) + 1) * sizeof(char));
        if (words[counter]->input_str == NULL)
        {
            fprintf(stderr, "memory problem\n");
            exit(-1);
        }
        strcpy(words[counter]->input_str, word_str);

        words[counter]->create_word = duplicate(word_str, how_many);
        // Superfluous because duplicate exits if there is an allocation error
        if (words[counter]->create_word == NULL)
        {
            fprintf(stderr, "error\n");
            exit(-1);
        }
        counter++;
        print(words, counter);

        do
        {
            printf("More (y/n)? ");
            if (scanf(" %c", &answer) != 1)
            {
                answer = 'n';
                break;
            }
        } while (answer != 'y' && answer != 'n');
    } while (counter < ARRAY_SIZE && answer == 'y');

    clean(words, counter);

    return(0);
}

void print(struct copy **words, int number)
{
    printf("Words (%d):\n", number);
    for (int i = 0; i < number; i++)
        printf("[%s] => [%s]\n", words[i]->input_str, words[i]->create_word);
}

char *duplicate(const char *str, int number)
{
    int len1 = strlen(str);
    int len2 = number * len1 + 1;
    char *space = malloc(len2);
    if (space == NULL)
    {
        fprintf(stderr, "memory allocation failed for %d bytes\n", len2);
        exit(-1);
    }
    for (int i = 0; i < number; i++)
        strcpy(&space[i * len1], str);
    space[len2 - 1] = '\0';     // In case number == 0
    return space;
}

void clean(struct copy **words, int number)
{
    for (int i = 0; i < number; i++)
    {
        free(words[i]->input_str);
        free(words[i]->create_word);
        free(words[i]);
        words[i] = NULL;
    }
}

结构体数组

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

struct copy
{
    char *input_str;
    char *create_word;
};

enum { ARRAY_SIZE = 20, STR_SIZE = 30 };

extern char *duplicate(const char *str, int number);
extern void print(struct copy *words, int number);
extern void clean(struct copy *words, int number);

int main(void)
{
    struct copy words[ARRAY_SIZE];
    char format_str[20];
    char word_str[STR_SIZE];
    int how_many;
    int counter = 0;
    char answer;
    sprintf(format_str, " %%%ds", STR_SIZE - 1);

    do
    {
        printf("Enter string: ");
        if (scanf(format_str, word_str) != 1)
            break;

        words[counter].input_str = (char *)malloc((strlen(word_str) + 1) * sizeof(char));
        if (words[counter].input_str == NULL)
        {
            fprintf(stderr, "memory problem\n");
            exit(-1);
        }
        strcpy(words[counter].input_str, word_str);

        printf("Enter integer: ");
        if (scanf(" %d", &how_many) != 1 || how_many < 0 || how_many > 999)
            break;

        words[counter].create_word = duplicate(word_str, how_many);
        // Superfluous because duplicate exits if there is an allocation error
        if (words[counter].create_word == NULL)
        {
            fprintf(stderr, "error\n");
            exit(-1);
        }
        counter++;
        print(words, counter);

        do
        {
            printf("More (y/n)? ");
            if (scanf(" %c", &answer) != 1)
            {
                answer = 'n';
                break;
            }
        } while (answer != 'y' && answer != 'n');
    } while (counter < ARRAY_SIZE && answer == 'y');

    clean(words, counter);

    return(0);
}

void print(struct copy *words, int number)
{
    printf("Words (%d):\n", number);
    for (int i = 0; i < number; i++)
        printf("[%s] => [%s]\n", words[i].input_str, words[i].create_word);
}

char *duplicate(const char *str, int number)
{
    int len1 = strlen(str);
    int len2 = number * len1 + 1;
    char *space = malloc(len2);
    if (space == NULL)
    {
        fprintf(stderr, "memory allocation failed for %d bytes\n", len2);
        exit(-1);
    }
    for (int i = 0; i < number; i++)
        strcpy(&space[i * len1], str);
    space[len2 - 1] = '\0';     // In case number == 0
    return space;
}

void clean(struct copy *words, int number)
{
    for (int i = 0; i < number; i++)
    {
        free(words[i].input_str);
        free(words[i].create_word);
        words[i].input_str = words[i].create_word = NULL;
    }
}

示例输出:

Enter string: abc
Enter integer: 1
Words (1):
[abc] => [abc]
More (y/n)? y
Enter string: def
Enter integer: 2
Words (2):
[abc] => [abc]
[def] => [defdef]
More (y/n)? y
Enter string: absolute-twaddle
Enter integer: 10
Words (3):
[abc] => [abc]
[def] => [defdef]
[absolute-twaddle] => [absolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddle]
More (y/n)? y
Enter string: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Enter integer: 0
Words (4):
[abc] => [abc]
[def] => [defdef]
[absolute-twaddle] => [absolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddleabsolute-twaddle]
[ABCDEFGHIJKLMNOPQRSTUVWXYZ] => []
More (y/n)? n

(两个程序对于相同的输入都给出相同的输出。两个程序都在 Valgrind 下干净地运行 - 该网站仍然不支持 https 连接。)

关于c - malloc/结构指针数组段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51920180/

相关文章:

c++ - 在段错误之前缺少 cout

segmentation-fault - 在 Zig 中使用 X11 C 库时出现段错误

C 使用 fread() 读取二进制文件

c - 二进制可执行文件是可移植的

c - 具有不同格式说明符的 scanf() 函数

c -++组((int)(值[i])/10);它有什么作用..?在 C

struct - 如何仅将某些结构成员设置为其默认值?

c++ - 是否可以使用代码块从文件运行一些案例测试而不使用文件函数

ios - swift 。无法更改结构的属性,收到表单数组

arrays - 如何从结构数组中获取 "select"列?