C - malloc/struct 指针数组 seg 错误



我在下面有这段代码,包括和其他在main中调用的函数是正确的。但是当我试图mallocwords[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 problemn");
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("errorn");
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 copy words[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 problemn");
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, "errorn");
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 bytesn", len2);
exit(-1);
}
for (int i = 0; i < number; i++)
strcpy(&space[i * len1], str);
space[len2 - 1] = '';     // 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 problemn");
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, "errorn");
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 bytesn", len2);
exit(-1);
}
for (int i = 0; i < number; i++)
strcpy(&space[i * len1], str);
space[len2 - 1] = '';     // 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连接的网站。

最新更新