黑客兰克问题(转换后) (C) 是什么导致了这个赛格错误?



我一直在hackerrank上尝试解决这个问题https://www.hackerrank.com/challenges/post-transition但我的代码似乎产生分割错误,当我试图运行它。我已经把它看了几十遍,并把它和别人的解决方案进行了比较,但我仍然不明白我可能做错了什么。

这是我得到的错误信息:

Reading symbols from Solution...done.
[New LWP 1602418]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./Solution'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  send_all_acceptable_packages (source=source@entry=0x16eeec8, 
source_office_index=0, target=target@entry=0x16eeee0, 
target_office_index=<optimized out>) at Solution.c:58
58      int src_pk_count = (source->offices[source_office_index].packages_count);

这是我的代码

#include <stdlib.h>
#include <string.h>
#define MAX_STRING_LENGTH 6
struct package
{
char* id;
int weight;
};
typedef struct package package;
struct post_office
{
int min_weight;
int max_weight;
package* packages;
int packages_count;
};
typedef struct post_office post_office;
struct town
{
char* name;
post_office* offices;
int offices_count;
};
typedef struct town town;

void print_all_packages(town t)
{
printf("%s:n",t.name);
//offices loop
for(int i=0;i<t.offices_count;i++)
{
printf("t%i:n",i);
//packages loop
for(int j=0;j<t.offices[i].packages_count;j++)
{printf("tt%sn", t.offices[i].packages[j].id);}
}

}
void send_all_acceptable_packages
(town* source, int source_office_index, town* target, int target_office_index)
{
int trg_pk_count = (target->offices[target_office_index].packages_count);
int src_pk_count = (source->offices[source_office_index].packages_count);

//weight condition

int min_w = (target->offices[target_office_index].min_weight);
int max_w = (target->offices[target_office_index].max_weight);

for(int i=0;i<src_pk_count;i++)
{

int pckg_w = (source->offices[source_office_index].packages[i].weight);

if ((pckg_w >= min_w) && (pckg_w <= max_w))
{



target->offices[target_office_index].packages = realloc                                 (target->offices[target_office_index].packages, sizeof(package)*                           (trg_pk_count+1));                 

(target->offices[target_office_index].packages_count)++;
(source->offices[source_office_index].packages_count)--;



target->offices[target_office_index].packages[(trg_pk_count)]=                           source->offices[source_office_index].packages[i];

for(int x=0; x<(src_pk_count-1);x++)
{
source->offices[source_office_index].packages[i+x] = source->offices                     [source_office_index].packages[i+x+1] ;


source->offices[source_office_index].packages= realloc(source->offices                   [source_office_index].packages, sizeof(package)*((source->offices                        [source_office_index].packages_count)));
}

}

}

}

town town_with_most_packages(town* towns, int towns_count)
{
//count
int town_pkcount[towns_count];
for(int i=0;i<towns_count;i++)
{
town_pkcount[i]=0;
int sum=0;
for(int j=0;j<towns[i].offices_count;j++)
{
sum+= towns[i].offices[j].packages_count;
}

town_pkcount[i]=sum;
}
//find max
int max=-1 , max_index;
for(int i=0; i<towns_count;i++)
{
if (town_pkcount[i]>max)
{
max = town_pkcount[i];
max_index=i;
}

}

return towns[max_index];

}
town* find_town(town* towns, int towns_count, char* name)
{
int town_index=-1;
for(int i=0; i<towns_count; i++)
{
if(strcmp(name,towns[i].name)==0)
{town_index = i;}

break;
}

return(&towns[town_index]);

}
int main()
{
int towns_count;
scanf("%d", &towns_count);
town* towns = malloc(sizeof(town)*towns_count);
for (int i = 0; i < towns_count; i++) {
towns[i].name = malloc(sizeof(char) * MAX_STRING_LENGTH);
scanf("%s", towns[i].name);
scanf("%d", &towns[i].offices_count);
towns[i].offices = malloc(sizeof(post_office)*towns[i].offices_count);
for (int j = 0; j < towns[i].offices_count; j++) {
scanf("%d%d%d", &towns[i].offices[j].packages_count, &towns[i].offices[j].min_weight, &towns[i].offices[j].max_weight);
towns[i].offices[j].packages = malloc(sizeof(package)*towns[i].offices[j].packages_count);
for (int k = 0; k < towns[i].offices[j].packages_count; k++) {
towns[i].offices[j].packages[k].id = malloc(sizeof(char) * MAX_STRING_LENGTH);
scanf("%s", towns[i].offices[j].packages[k].id);
scanf("%d", &towns[i].offices[j].packages[k].weight);
}
}
}
int queries;
scanf("%d", &queries);
char town_name[MAX_STRING_LENGTH];
while (queries--) {
int type;
scanf("%d", &type);
switch (type) {
case 1:
scanf("%s", town_name);
town* t = find_town(towns, towns_count, town_name);
print_all_packages(*t);
break;
case 2:
scanf("%s", town_name);
town* source = find_town(towns, towns_count, town_name);
int source_index;
scanf("%d", &source_index);
scanf("%s", town_name);
town* target = find_town(towns, towns_count, town_name);
int target_index;
scanf("%d", &target_index);
send_all_acceptable_packages(source, source_index, target, target_index);
break;
case 3:
printf("Town with the most number of packages is %sn", town_with_most_packages(towns, towns_count).name);
break;
}
}
return 0;
}

请记住,结构体和main函数已经预先写好了

seg故障似乎与send_all_acceptable_packages函数有关

还要记住,在输入这行输入之后会发生segfault2 B 0 A 1触发main

中的情形2
case 2:
scanf("%s", town_name);
town* source = find_town(towns, towns_count, town_name);
int source_index;
scanf("%d", &source_index);
scanf("%s", town_name);
town* target = find_town(towns, towns_count, town_name);
int target_index;
scanf("%d", &target_index);
send_all_acceptable_packages(source, source_index, target, target_index);
break;

在中,您可以看到find_town函数的返回值被用作send_all_acceptable_packages函数的输入,这使我相信错误存在于这两个函数

中的一个。请帮我找出这里的问题,谢谢你的建议。

下面的循环永远不会迭代:

town* find_town(town* towns, int towns_count, char* name)
{
int town_index=-1;
int i = 0;

for(i=0; i < towns_count; i++)<-warning points here (i++)
{
if(strcmp(name,towns[i].name)==0)
{ town_index = i;}   
break;<- cause of warning
}
return(&towns[town_index]);
}

我从调试器中看到以下警告:

150,31警告:将永远不会执行

break语句保证循环永远不会迭代。

您可能打算将它放在if()语句

town* find_town(town* towns, int towns_count, char* name)
{
int town_index=-1;
int i = 0;

for(i=0; i < towns_count; i++)
{
if(strcmp(name,towns[i].name)==0)
{ 
town_index = i;
break;
}   

}
return(&towns[town_index]);
}

一些额外的项目看:

  • int main(void);C(不是int main())中main函数的最小原型
  • 代码不检查应该检查的函数的返回值(例如scanf())。
  • 最好限制呼叫scanf()的输入长度以防止溢出,即使用#define MAX_STRING_LENGTH 6,用户被限制为一些非常短的名称,但如果城市输入为"达拉斯";scanf("%s", towns[i].name);程序将溢出。将其写入scanf("%(MAX_STRING_LENGTH-1)s", towns[i].name);以限制用户输入的合法长度。
  • 建议将#define MAX_STRING_LENGTH 6更改为更实际的值
  • 内存泄漏。代码不会释放创建的任何内存。每调用一次malloc(),调用一次free()
  • 在每个scanf()之前使用printf()列出用户输入的指令。(例如:printf("enter town namen");)

相关内容

  • 没有找到相关文章

最新更新