我编写 C 代码以在编程和学习方面做得更好......并具有应生成静态网页的程序。它还将项目保存为文本文件。我有单独的函数来制作对象(realloc 并放置一个新结构......(,并将问题代码提取到一个简短的程序中......这只是为了阅读"项目"。当我运行时,它说:
分段故障(核心转储(
在print_1_content中间
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SELL_ITEM 1
#define PARAGRAPH_ITEM 2
struct SellItem {
char title[50];
int nr_of_img;
char ** image_files;//array of strings
};
struct ParagraphItem{
char * text;
};
union ContentItem{//one of the following only
struct SellItem s_item;
struct ParagraphItem p_item;
};
struct Content{
int type;//1=sellitem 2=paragraph
union ContentItem c_item;
};
int open_items_file(struct Content **, int *, char *);
int free_1_item(struct Content *);
struct Content import_1_content(char *);
void increase(struct Content**, int *);
void print_1_content(struct Content *);
struct Content import_1_content(char *);
int free_1_item(struct Content *);
int main (void)
{
struct Content * content;
int content_count=0;
open_items_file(&content, &content_count, "all_items.txt");
return 0;
}
int open_items_file(struct Content ** content, int * number_of_content, char * filename){
printf("open_items_file %sn", filename);
FILE *fp = fopen(filename, "r");
char * line = NULL;
size_t len = 0;
ssize_t read;
int counter=0;
if(fp==NULL){
return 0;
}
//for each row
while ((read = getline(&line, &len, fp)) != -1) {
if((line[0]=='S' || line[0]=='P') && line[1]=='-'){
if(line[3]==':'){
if(line[2]=='I'){
increase(content, number_of_content);
*content[(*number_of_content)-1] = import_1_content(line);
}
else{
//not sell/paragraph item
}
}//end if line[3]==':'
}//end if line[0] =='S' eller 'P'
counter++;
}
free(line);
fclose(fp);
return counter;
}
void increase(struct Content** content, int *nr_of_content){
if((*nr_of_content)==0){
*content = malloc(sizeof(struct Content));
}
else{
*content = realloc(*content, (*nr_of_content+1) * sizeof(struct Content));
}
(*nr_of_content)++;
}
void print_1_content(struct Content * content){
//Print info
}
struct Content import_1_content(char * text_line){
struct Content temp_content_item;
char * line_pointer = text_line;
char c;
line_pointer += 4;
if(text_line[0]=='S'){
temp_content_item.type = SELL_ITEM;
temp_content_item.c_item.s_item.nr_of_img=0;
int i=0;
char * temp_text;
while(*line_pointer != '|' && *line_pointer != 'n' && i < sizeof(temp_content_item.c_item.s_item.title)-1){
temp_content_item.c_item.s_item.title[i] = *line_pointer;
i++;//target index
line_pointer++;
}
temp_content_item.c_item.s_item.title[i]=' ';
i=0;
//maybe images?
short read_img_counter=0;
if(*line_pointer == '|'){
line_pointer++; //jump over '|'
//img-file-name separ. by ';', row ends by 'n'
while(*line_pointer != 'n'){//outer image filename -loop
i=0;
while(*line_pointer != ';' && *line_pointer != 'n'){//steps thr lett
c = *line_pointer;
if(i==0){//first letter
temp_text = malloc(2);
}
else if(i>0){
temp_text = realloc(temp_text, i+2);//extra for ' '
}
temp_text[i] = c;
line_pointer++;
i++;
}
if(*line_pointer==';'){//another image
line_pointer++;//jump over ';'
}
else{
}
temp_text[i]=' ';
//allocate
if(read_img_counter==0){//create array
temp_content_item.c_item.s_item.image_files = malloc(sizeof(char*));
}
else{//extend array
temp_content_item.c_item.s_item.image_files = realloc(temp_content_item.c_item.s_item.image_files, sizeof(char*) * (read_img_counter+1));
}
//allocate
temp_content_item.c_item.s_item.image_files[read_img_counter] = calloc(i+1, 1);
//copy
strncpy(temp_content_item.c_item.s_item.image_files[read_img_counter], temp_text, strlen(temp_text));
read_img_counter++;
temp_content_item.c_item.s_item.nr_of_img = read_img_counter;
}
}
else{
printf("Item had no img-filesn");
}
}
else{ // text_line[0]=='P'
temp_content_item.type = PARAGRAPH_ITEM;
temp_content_item.c_item.p_item.text = calloc(strlen(text_line)-4,1);
int i=0;
while(*line_pointer != ' ' && *line_pointer != 'n'){
temp_content_item.c_item.p_item.text[i] = *line_pointer;
i++;
line_pointer++;
}
}
print_1_content(&temp_content_item);
return temp_content_item;
}
int free_1_item(struct Content * item){
if(item->type==SELL_ITEM){
if(item->c_item.s_item.nr_of_img > 0){
//Freeing img-names
for(int i=0; i<item->c_item.s_item.nr_of_img; i++){
free(item->c_item.s_item.image_files[i]);
}
}
return 1;
}
else if(item->type==PARAGRAPH_ITEM){
//freeing p_item
free(item->c_item.p_item.text);
return 1;
}
else{
printf("error: unknown itemn");
}
return 0;
}
要读取的文本文件 (all_items.txt( 如下所示,以换行符结尾,适用于"销售项目"和"段落项目"两种内容类型:
S-I:Shirt of cotton|image1.jpg;image2.jpg;image3.jpg
P-I:A paragraph, as they are called.
S-I:Trousers, loose style|image4.jpg
所以你发现的问题就出在这一行:
*content[(*number_of_content)-1] = temp_content_item2;
这是因为操作优先级*content[(*number_of_content)-1]
和(*content)[(*number_of_content)-1]
不一样,它实际上是在做*(content[(*number_of_content)-1])
。因此,您的代码正在执行数组索引,然后取消引用,该索引指向内存中的某个随机位置。将该行替换为此行,这将解决当前问题。
(*content)[(*number_of_content)-1] = temp_content_item2;