C
相对较新,我很容易承认有些东西我认为我理解,但可能不欣赏所有的细微差别。这是从我编写的一个更复杂的程序中提取的MWE。它编译和运行良好,但测试显示ev->pin
的值最初是正确的,但在不相关的函数调用后就不正确了(在代码中查找?)看起来内存不知何故被践踏了,但我不知道发生了什么。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define SCAN_EVENT_COUNT 5
#define PIN_ASSIGNMENTS {7, -1, 1, 13, 4}
#define EVENT_NAMES "first-second-third-fourth-fifth"
void init_scan_events();
int parse_string(char pInputString[],
char *Delimiter,
char *pToken[]);
struct scan_events
{
char event_names[31];
char *pEvent[SCAN_EVENT_COUNT];
int pin[SCAN_EVENT_COUNT];
};
int main(void)
{
init_scan_events();
return (0);
}
/**
* the following function from https://stackoverflow.com/a/2091906/633251
* Note that `strtok` expects a `char * string` and `char * delimiter` as arguments.
**/
int parse_string(char pInputString[],
char *Delimiter,
char *pToken[])
{
int i = 0;
pToken[i] = strtok(pInputString, Delimiter); // get first token
i++;
while ((pToken[i] = strtok(NULL, Delimiter)) != NULL) // get the rest of the tokens
{
i++;
}
return i;
}
void init_scan_events()
{
char en[] = EVENT_NAMES;
int en_size = strlen(en);
int size = SCAN_EVENT_COUNT;
int pin[] = PIN_ASSIGNMENTS;
int token_count = 0;
char *Delim = "-";
int i;
struct scan_events *ev = malloc(sizeof(struct scan_events));
if (ev == NULL)
{
printf("Allocation failed\n");
}
for (int i = 0; i < en_size; i++) // copy EVENT_NAMES
{
ev->event_names[i] = en[i];
}
for (int i = 0; i < size; i++) // copy PIN_ASSIGNMENTS
{
ev->pin[i] = pin[i];
}
for (int i = 0; i < size; i++)
{
printf("% d ", ev->pin[i]); // ??? inspect pin values: correct!
}
printf("\n");
token_count = parse_string(ev->event_names, Delim, ev->pEvent); // tokenize EVENT_NAMES
for (int i = 0; i < size; i++)
{
printf("% d ", ev->pin[i]); // ??? check pin values: corrupted!
}
printf("\n");
free(ev);
}
字符串
1条答案
按热度按时间a14dhokn1#
1.这是
parse_string()
中分配pToken[5] = NULL
的缓冲区溢出。我建议传入SCAN_EVENT_REQ并使用它来限制i < 5
。ev->event_names
不能以“\0”终止,这将触发strtok()
中需要字符串的未定义行为。运行<= en_size
的循环或使用strcpy()
。char event_names[31]
不够大。不要重复。在这种情况下是投影strlen(EVENT_NAMES) == 31
,所以它应该是strlen(EVENT_NAMES) + 1
,或者因为你有数组,所以只使用sizeof
。1.如果malloc失败了,你就不能使用
ev
了。使用exit(1)
并不是不合理的,因为你可能对它无能为力。1.优化了
init_scan_events()
(离开),以专注于上述问题。字符串
示例运行:
型