在 c 中使用 qsort 对结构进行排序时解决边界错误
address boundary error while sorting struct with qsort in c
我有一个结构,我想按 ID 对其进行排序,然后删除具有 NULL
ID 的条目。但是我收到地址边界错误。不太确定是什么问题。
typedef struct data_id
{
char* id;
int marker;
int key;
} data_id;
我的比较功能:
int cmp(const void *p1, const void *p2)
{
const data_id *v1 = (data_id *)p1;
const data_id *v2 = (data_id *)p2;
if (v1->id < v2->id)
return -1;
else if (v1->id > v2->id)
return +1;
else
return 0;
}
我在主函数中调用 qsort 时使用:
qsort(nodeList, num_id, sizeof(nodeList),cmp);
num_id
是条目的 number
。
But anyway you need to show a minimal reproducible example
我正在从标准输入读取数据并创建列表。
void create_list(input){
nodeList = realloc(nodeList, sizeof *nodeList * 10000);
if (input == 65) // A
{
stop_flag = true;
s_flag = true;
}
else if (input == 73) // I
{
moves_flag = true;
}
else if (s_flag == true && (islower(input) || isdigit(input)))
{
start_node = input;
s_flag = false;
}
else if (moves_flag == true && isdigit(input))
{
num_moves = (char)input - '0';
moves_flag = false;
}
else if ((islower(input) || isdigit(input)) && !stop_flag )
{
if (m_flag == true && isdigit(input))
{
nodeList[tmp_id].marker = digitconcat(nodeList[tmp_id].marker,input);
}
else if (m_flag == false && (isdigit(input)||islower(input)))
{
buffer[0] = (char)input;
if (buffer_size == 0)
{
nodeList[num_id].id = strconcat(1, buffer);
buffer_size++;
}
else
nodeList[num_id].id = strconcat(2, nodeList[num_id].id, buffer);
m_flag = false;
}
}
else if (input == '-' && !stop_flag)
{
m_flag = true;
}
else if (input == '\n' && !stop_flag)
{
tmp_id++;
num_id++;
buffer_size = 0;
nodeList[tmp_id].marker = 0;
nodeList[num_id].key = num_id;
m_flag = false;
}
else if ((input == ',' || input == ':') && !stop_flag)
{
buffer_size = 0;
num_id++;
nodeList[tmp_id].marker = 0;
nodeList[num_id].key = num_id;
m_flag = false;
}
}
字符串和数字的连接函数是:
unsigned digitconcat(unsigned x, unsigned y)
{
y = (char)y - '0';
unsigned pow = 10;
while (y >= pow)
pow *= 10;
return x * pow + y;
}
char *strconcat(int count, ...)
{
va_list ap;
int i;
// Find required length to store merged string
int len = 1; // room for NULL
va_start(ap, count);
for (i = 0; i < count; i++)
len += strlen(va_arg(ap, char *));
va_end(ap);
// Allocate memory to concat strings
char *merged = calloc(sizeof(char), len);
int null_pos = 0;
// Actually concatenate strings
va_start(ap, count);
for (i = 0; i < count; i++)
{
char *s = va_arg(ap, char*);
strcpy(merged + null_pos, s);
null_pos += strlen(s);
}
va_end(ap);
return merged;
}
示例输入可以是:
aqwe:b66,g
b66:g,l-23452
asfag:l
l:-2424
A:g
I:5
由 :
、,
或 LF
分隔的字符串是 IDs
。在 -
之后跟随标记。最后两行不需要保存在列表中。
我也不知道为什么我的列表的最后一个条目被添加到它,因为我专门设置了 stop_flag
,停止添加 ID
、Key
或Marker
到达倒数第二行的 A
之后。
What is nodeList?
数据应该表示图表。 nodes
由 :
、,
或 LF
分隔。 weight(marker)
是破折号后面的数字,它属于它所在行的第一个节点。此外,我给每个节点一个特定的 'key'。哦,同一条线上的每个节点都已连接。所以 nodeList
是存储图中每个节点信息的数组。
但我只是认为也许数组不是存储数据的最佳数据结构,因为它更难去除重复项。
所以我最终没有使用 qsort
,而是在一些帮助下自己写了一个:
void sort()
{
data_id tmp;
for (int i = 0; i < num_id; ++i)
{
for (int j = i + 1; j < num_id; ++j)
{
// swapping strings if they are not in the lexicographical order
if (strcmp(nodeList[i].id, nodeList[j].id) > 0)
{
tmp = nodeList[i];
nodeList[i] = nodeList[j];
nodeList[j] = tmp;
}
}
}
}
读取所有内容后调用该函数。
我有一个结构,我想按 ID 对其进行排序,然后删除具有 NULL
ID 的条目。但是我收到地址边界错误。不太确定是什么问题。
typedef struct data_id
{
char* id;
int marker;
int key;
} data_id;
我的比较功能:
int cmp(const void *p1, const void *p2)
{
const data_id *v1 = (data_id *)p1;
const data_id *v2 = (data_id *)p2;
if (v1->id < v2->id)
return -1;
else if (v1->id > v2->id)
return +1;
else
return 0;
}
我在主函数中调用 qsort 时使用:
qsort(nodeList, num_id, sizeof(nodeList),cmp);
num_id
是条目的 number
。
But anyway you need to show a minimal reproducible example
我正在从标准输入读取数据并创建列表。
void create_list(input){
nodeList = realloc(nodeList, sizeof *nodeList * 10000);
if (input == 65) // A
{
stop_flag = true;
s_flag = true;
}
else if (input == 73) // I
{
moves_flag = true;
}
else if (s_flag == true && (islower(input) || isdigit(input)))
{
start_node = input;
s_flag = false;
}
else if (moves_flag == true && isdigit(input))
{
num_moves = (char)input - '0';
moves_flag = false;
}
else if ((islower(input) || isdigit(input)) && !stop_flag )
{
if (m_flag == true && isdigit(input))
{
nodeList[tmp_id].marker = digitconcat(nodeList[tmp_id].marker,input);
}
else if (m_flag == false && (isdigit(input)||islower(input)))
{
buffer[0] = (char)input;
if (buffer_size == 0)
{
nodeList[num_id].id = strconcat(1, buffer);
buffer_size++;
}
else
nodeList[num_id].id = strconcat(2, nodeList[num_id].id, buffer);
m_flag = false;
}
}
else if (input == '-' && !stop_flag)
{
m_flag = true;
}
else if (input == '\n' && !stop_flag)
{
tmp_id++;
num_id++;
buffer_size = 0;
nodeList[tmp_id].marker = 0;
nodeList[num_id].key = num_id;
m_flag = false;
}
else if ((input == ',' || input == ':') && !stop_flag)
{
buffer_size = 0;
num_id++;
nodeList[tmp_id].marker = 0;
nodeList[num_id].key = num_id;
m_flag = false;
}
}
字符串和数字的连接函数是:
unsigned digitconcat(unsigned x, unsigned y)
{
y = (char)y - '0';
unsigned pow = 10;
while (y >= pow)
pow *= 10;
return x * pow + y;
}
char *strconcat(int count, ...)
{
va_list ap;
int i;
// Find required length to store merged string
int len = 1; // room for NULL
va_start(ap, count);
for (i = 0; i < count; i++)
len += strlen(va_arg(ap, char *));
va_end(ap);
// Allocate memory to concat strings
char *merged = calloc(sizeof(char), len);
int null_pos = 0;
// Actually concatenate strings
va_start(ap, count);
for (i = 0; i < count; i++)
{
char *s = va_arg(ap, char*);
strcpy(merged + null_pos, s);
null_pos += strlen(s);
}
va_end(ap);
return merged;
}
示例输入可以是:
aqwe:b66,g
b66:g,l-23452
asfag:l
l:-2424
A:g
I:5
由 :
、,
或 LF
分隔的字符串是 IDs
。在 -
之后跟随标记。最后两行不需要保存在列表中。
我也不知道为什么我的列表的最后一个条目被添加到它,因为我专门设置了 stop_flag
,停止添加 ID
、Key
或Marker
到达倒数第二行的 A
之后。
What is nodeList?
数据应该表示图表。 nodes
由 :
、,
或 LF
分隔。 weight(marker)
是破折号后面的数字,它属于它所在行的第一个节点。此外,我给每个节点一个特定的 'key'。哦,同一条线上的每个节点都已连接。所以 nodeList
是存储图中每个节点信息的数组。
但我只是认为也许数组不是存储数据的最佳数据结构,因为它更难去除重复项。
所以我最终没有使用 qsort
,而是在一些帮助下自己写了一个:
void sort()
{
data_id tmp;
for (int i = 0; i < num_id; ++i)
{
for (int j = i + 1; j < num_id; ++j)
{
// swapping strings if they are not in the lexicographical order
if (strcmp(nodeList[i].id, nodeList[j].id) > 0)
{
tmp = nodeList[i];
nodeList[i] = nodeList[j];
nodeList[j] = tmp;
}
}
}
}
读取所有内容后调用该函数。