使用结构更新指针进行重新分配时出现问题

时间:2019-06-30 07:47:54

标签: c visual-studio

我正在尝试创建结构的自扩展数组。我看到了问题hereherehere,但答案似乎不适用于我的情况。

我很幸运地使用了这种使用字符串数组的技术,但是使用结构不起作用。下面是代码:

mvc.perform( MockMvcRequestBuilders
      .post("/users")
      .content(asJsonString(new UserVO(null, "firstName4", "lastName4", 
  "user1@yahoo.com")))
      .contentType(MediaType.APPLICATION_JSON)
      .accept(MediaType.APPLICATION_JSON))
      .andExpect(status().isCreated())
      .andExpect(MockMvcResultMatchers.jsonPath("$.userId").exists());
    enter code here

  <br>
# I think the issue is with parsing to json.  check content parsing in the above code.

这是C代码。

//  SO1.h
//
#pragma once

typedef struct {
    int tag;
    int type;
}structure;

void addElement(structure* Tkn_A, const int Tag);

void listArray();

程序无法正常完成时,在执行// SO1.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include "stdio.h" #include "malloc.h" #include "SO1.h" const int ARRAY_INITIAL_SIZE = 2; const int ARRAY_ADDITIONAL_SIZE = ARRAY_INITIAL_SIZE / 2; structure* userArray; size_t userArrayLength = -1; size_t userArrayAvailable = ARRAY_INITIAL_SIZE; int main() { userArray = (structure*)malloc(userArrayAvailable * sizeof(structure)); printf(" orgarrptr=%p\n", userArray); addElement(userArray, 13); addElement(userArray, 14); addElement(userArray, 15); addElement(userArray, 16); addElement(userArray, 17); addElement(userArray, 18); addElement(userArray, 19); addElement(userArray, 20); addElement(userArray, 21); addElement(userArray, 22); addElement(userArray, 23); addElement(userArray, 24); addElement(userArray, 25); } void addElement(structure* userArray, const int tag) { userArrayLength++; if (userArrayLength > userArrayAvailable) { userArrayAvailable += ARRAY_ADDITIONAL_SIZE; structure* originalUserArrayPtr = userArray; printf(" orgarrptr=%p\n", originalUserArrayPtr); userArray = (structure*)realloc(userArray, userArrayAvailable * sizeof(structure)); printf(" newarrptr=%p\n", userArray); if (originalUserArrayPtr != userArray) { printf("pointers different\n"); } } userArray[userArrayLength].tag = tag; userArray[userArrayLength].type = 1; printf("%2d %d\n\n", userArray[userArrayLength].tag, userArray[userArrayLength].type); listArray(); } void listArray() { for (size_t i = 0; i <= userArrayLength; i++) { printf("%2d %d\n", userArray[i].tag, userArray[i].type); } } 的行上出现以下错误:

realloc

Debug Assertion Failed! File: minkernel\crts\ucrt\src\appcrt\heap.cpp Line: 604 Expression _CrtIsValidHeapPointer(block) 提出的指针与原始指针具有不同的长度时,就会发生这种情况。但是,下次我查看该指针时,它仍然具有旧指针的值。以下是一次运行的输出:

realloc

有人知道会导致此问题的原因吗? TIA。

很抱歉,这个问题很长,但我想提供所有详细信息。我认为Visual Studio与问题无关,但不确定。我正在使用VS Community Edition 2019,16.1.3。

更新:最初我有两个问题。一个获取指针更新,另一个获取垃圾数据。我决定将两者分为两个不同的问题。

1 个答案:

答案 0 :(得分:3)

恕我直言,OP尚不了解变量的范围:

void addElement(structure* userArray, const int tag)
{
  /* The global variable userArray is now invisible (eclipsed).
   * Instead, the local parameter userArray is used.
   * It has its own storage.
   */
}

因此,只要realloc()返回一个不同的地址,然后再离开addElement()就会丢失它。

realloc()可能会返回

  1. (第一个参数的)给定地址
  2. 新地址
  3. NULL指针。

realloc()内部使用的堆管理可能会认识到块增长之后的内存仍然可用。因此,该块可以在适当位置生长。也可能是堆管理提供了比实际请求大的块的时间。 (这可能是防止堆内存碎片的一种策略。)这就是为什么尽管请求的内存比以前更多的原因仍可能返回相同地址的原因。

如果以上均不适用,则分配新块,将旧内容复制到新地址,并释放旧块。 (否则,它将成为内存泄漏。)

如果realloc()无法执行上述任何一项操作,则返回NULL

回顾上面的内容,甚至更糟:每当realloc()返回一个不同的地址时,旧地址的内存就被释放。因此,全局userArray(未更新)变得悬而未决(指向已释放的内存)。访问悬空指针是未定义行为→对于任何奇怪的效果(包括崩溃(访问冲突))都有好处。

关于第三个:

userArray = (structure*)realloc(userArray, userArrayAvailable * sizeof(structure));

可能看起来有问题。

(我对此的个人想法是:超出内存时,这通常意味着情况非常错误。该过程通常必须尽快终止。在大多数平台上,当NULL指针会发生这种情况被访问时忽略了丑陋的系统错误消息可能会吓the用户并迫使她/他拨打支持电话的事实。另外,请注意我反复使用“通常” ...)

OP已经观察到诊断输出中的点1.和2.。

有多种方法可以解决此问题:

  1. 摆脱全局变量偏食:
void addElement(const int tag)
{
  /* unmodified code will now access the global userArray */
}
  1. 改为使用指向指针的指针:
void addElement(structure **userArray, const int tag)
{
  /* all uses of userArray in code have to get an additional indirection operator
   * i.e. replace all occurrences of "userArray" by "(*userArray)"
   */
}
  1. 返回(可能更改)userArray作为结果:
structure* addElement(structure *userArray, const int tag)
{
  /* unmodified code */
  return userArray;
}

必须立即致电:

userArray = addElement(userArray, 13);

将(可能更改的)指针重新分配给全局变量。


我(个人)通常更喜欢设计3。但是,考虑到addElement()也会访问各种其他全局变量,在我看来,选项1似乎是最一致的解决方法。