c - malloc/struct 指针数组段错误
问题描述
我在下面有这段代码,包含和其他调用的函数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);
}
解决方案
这是您的代码的两个版本,一个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
连接的站点。)
推荐阅读
- r - 在 R 中,如何制作一个六条形图,其中每个条形包含一系列数据?
- lua - 使用 NUI 的 FiveM 车辆额外列表
- javascript - 数据()中的Vue警告错误“TypeError:无法将未定义或空值转换为对象”
- amazon-web-services - 使用 Lambda 交换 Elastic Beanstalk URL
- swiftui - 在按钮中单击时将图像添加到按钮
- java - Cucumber Selenium (Java) - PageFactory - NullPointException 获取 URL
- c# - 在 Connect c# 上获取 iphone 的 UDID
- python - python-rq scheduler 统计作业执行的次数
- python - 使用 OOP 时如何避免代码重复
- python - 使用 tensorflow 2.0 进行模型预测会导致 python 内核死机并重新启动