我在下面有这段代码,包括和在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);
}
答案 0 :(得分:1)
这是您的代码的两个版本,一个在struct copy *words[ARRAY_SIZE];
顶部使用main()
,另一个使用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 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
连接。)