我有一个链接的srtings列表,我需要按字母顺序排序 我正在尝试将字符串复制到数组中,然后按字母顺序对它们进行排序和打印
void DisplayAll(k *l,p *p)
{
int i,j;
p *temp;
temp = malloc(l->num*sizeof *temp);
for (i = 0; i < l->num; i++)
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
i++;
}
for (i = 0; i < l->num - 1; i++){
for (j = i + 1; j< l->num; j++)
{
if (strcmp(temp[i].name, temp[j].name) > 0)
{
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
}
}
for (i = 0; i < l->num-1; i++){
printf("%s\n", temp[i].name);
}
}
这是k结构和p stuct
typedef struct p
{
char name[20];
struct p* next;
}p;
typedef struct k
{
int num;
p *head;
}k;
我得到一个错误evey时间我运行它
答案 0 :(得分:2)
您的代码存在一些问题:
首先关闭 :这看起来并不正确:
strcpy_s(temp->name,20, temp[i].name);
strcpy_s(temp->name[i],20, temp[j].name);
strcpy_s(temp->name[j],20, temp->name);
根据the docs:
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements,
const char *strSource
);
第一个和最后一个参数应该是char*
类型。您已将struct p .name
定义为char[20]
,因此temp->name[i]
的类型为char
。
我猜你实际上是在尝试做这样的事情:
//get struct p at offset i in temp, access member "name"
strcpy_s(temp[i].name, 20, temp[j].name);
其次 :您正在为temp
分配内存,但是一旦完成,您就无法free
(即函数返回)。换句话说,你有内存泄漏。当然,一旦你的程序退出,内存几乎肯定会被释放,但如果你正在编写必须长时间运行的程序,并且这样的函数被多次调用,你的内存消耗会逐渐消耗增加,你不希望这种情况发生。简而言之,在你的最后一个循环(你打印出来的所有东西)之后,添加:
free(temp);
您现在已添加free
来电,并且 - 正确地将其包裹在if (temp)
中。但是:如果malloc
返回了一个NULL
指针,那么您认为在功能开始时您是不是应该这么做?
temp = malloc(l->num * sizeof *temp);
if (!temp)
return;//or return int to indicate error or or exit EXIT_FAILURE; or something
没有理由让你在没有成功分配内存的情况下达到free(temp)
的目的。
第三 :正如@Bluepixy在评论中所指出的那样,也存在语法错误:if (strcmp(temp[i].name, temp[j].name) > 0)
分支从未正确关闭:你是在第三次strcpy_s
电话后错过了一个结束括号。
最后 ,您正在分配足够的内存来容纳l->num
结构。您初始化它们的方式是为每个其他结构分配一个列表中下一个name
的{{1}}成员。你并没有真正确保struct p
不是空指针。这可能会导致问题(取消引用空指针)。因此,将第一个循环更改为以下内容:
p->next
在此之后,使用int l_num = l->num;//you'll see why
for (i = 0; i < l_num; i+=2)//increment twice if you want/need to
{
strcpy_s(temp[i].name, 20, p->name);
p = p->next;
if (p == NULL)
{
l_num = i+1;//this is as far as we ought to go in the subsequent loops
break;//or handle error in some way
}
}
或;i < l->num;
替换循环中的所有i < l_num
条件,以避免使用未初始化的字符串值。
只是最后一个提示 :如果您没有处理过于时间关键的事情,那么使用j < l_num
代替{{1}可能会有用,尤其是在处理字符串时,或使用calloc
确保所有malloc
成员确实是空字符串。
如果您发现自己使用了很多memset(temp[i]->name, 0, 20);
函数(char[]
,str*
等),即使像strncat
这样简单的事情也可以让生活变得更轻松。