C 为什么在这种情况下会导致内存访问异常?
我有以下代码需要格式化输出。但当我这样做时,一个内存异常导致了无效内存访问异常。我做错了什么?请给我一些建议C 为什么在这种情况下会导致内存访问异常?,c,exception,memory,C,Exception,Memory,我有以下代码需要格式化输出。但当我这样做时,一个内存异常导致了无效内存访问异常。我做错了什么?请给我一些建议 char* strData = malloc(tag_operation_report->tag.epc.size / 2), char* strTemp= malloc(tag_operation_report->tag.epc.size / 2); do { for (int i = 0; i < tag_operation_rep
char* strData = malloc(tag_operation_report->tag.epc.size / 2),
char* strTemp= malloc(tag_operation_report->tag.epc.size / 2);
do
{
for (int i = 0; i < tag_operation_report->tag.epc.size / 2; i++)
{
uint32_t num = tag_operation_report->tag.epc.bytes[i];
strTemp=sprintf(L"%x ", num);
strData+=strTemp;
}
} while (tag_operation_report->tag.epc.size != 0);
data = (void *)strData;
free(strTemp);
free(strData);
sprintf只修改已经分配的内存。必须将目标缓冲区指针作为第一个参数传递 如果您不能100%确定输出是否适合您的缓冲区,那么最好使用snprintf,它还需要一个参数来告诉您缓冲区中还有多少空间。这可以防止由sprintf写入超过缓冲区结尾引起的错误。这是一个错误:sprintfL%x,num sprintf的第一个参数是一个分配的缓冲区,输出将被放入其中。第二个参数是格式字符串 因此,您试图覆盖字符串文字L%x,并且num不是有效的格式字符串。您的编译器应该警告您这个错误-请注意编译器的输出 执行strTemp=也是一个错误,strTemp+=strData也是一个错误。您不能添加指针,编译器也应该对此发出警告 另一个错误是data=void*strData;自由贸易数据,这使得数据指向已释放的内存 如果您试图连接字符串,那么您的操作完全是错误的。您需要理解指针不是字符串。指针指向可能包含字符串的内存区域。您必须考虑已分配的内存块以及指针指向的位置 问题1 您正在为strTemp分配一个int,它是char*。我很惊讶你的编译器没有警告你。不清楚你的目标是什么 问题2 同样,编译器应该告诉您这是一个错误。不能将一个字符*增加另一个字符* 问题3 您正在调用与malloc返回的值不同的指针值。这会导致未定义的行为 建议的解决方案 也许这就是你想要做的:
// Don't need to use dynamic memory allocation for this.
// It's only going to be used in sprintf. 20 characters should
// be large enough for that.
char strTemp[20];
// Bootstrap strData.
int strDataSize = 0;
char* strData = malloc(1);
// If memory allocation failed, deal with the problem
if ( strData == NULL )
{
exit(EXIT_FAILURE);
}
strData[0] = '\0';
for (int i = 0; i < tag_operation_report->tag.epc.size / 2; i++)
{
uint32_t num = tag_operation_report->tag.epc.bytes[i];
sprintf(strTemp, "%x ", num);
// Increase the size of strData
strDataSize += strlen(strTemp);
// Allocate more memory for strData.
strData = realloc(strData, strDataSize + 1);
// If memory allocation failed, deal with the problem
if ( strData == NULL )
{
exit(EXIT_FAILURE);
}
// Add strTemp to strData.
strcat(strData, strTemp);
}
data = (void *)strData;
// Don't free strData. If you do, data will be dangling pointer.
// free(strData);
如何从for循环中获取每个值并连接它们?请给马约兰一些建议。您必须自己分配所需的内存量。没有魔法。问题1的目标很明显。他认为sprintf返回格式化字符串,而不是将其作为第一个参数。这个错误会造成大量其他问题,比如写入字符串常量格式字符串,并将uint32_t num强制转换为const char*格式。@PeterCordes,在再次阅读文章后,您的评论是有意义的。
strTemp=sprintf(L"%x ", num);
strData+=strTemp;
free(strTemp);
free(strData);
// Don't need to use dynamic memory allocation for this.
// It's only going to be used in sprintf. 20 characters should
// be large enough for that.
char strTemp[20];
// Bootstrap strData.
int strDataSize = 0;
char* strData = malloc(1);
// If memory allocation failed, deal with the problem
if ( strData == NULL )
{
exit(EXIT_FAILURE);
}
strData[0] = '\0';
for (int i = 0; i < tag_operation_report->tag.epc.size / 2; i++)
{
uint32_t num = tag_operation_report->tag.epc.bytes[i];
sprintf(strTemp, "%x ", num);
// Increase the size of strData
strDataSize += strlen(strTemp);
// Allocate more memory for strData.
strData = realloc(strData, strDataSize + 1);
// If memory allocation failed, deal with the problem
if ( strData == NULL )
{
exit(EXIT_FAILURE);
}
// Add strTemp to strData.
strcat(strData, strTemp);
}
data = (void *)strData;
// Don't free strData. If you do, data will be dangling pointer.
// free(strData);