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);