Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
错误的原因是什么;malloc:**对象0x7b的错误:未分配要释放的指针";_C_Malloc_Free_Runtime Error - Fatal编程技术网

错误的原因是什么;malloc:**对象0x7b的错误:未分配要释放的指针";

错误的原因是什么;malloc:**对象0x7b的错误:未分配要释放的指针";,c,malloc,free,runtime-error,C,Malloc,Free,Runtime Error,我正在为一个班写这个程序。这个程序是一个使用堆栈的简单括号检查器应用程序。在本例中,我使用了静态数组来实现堆栈数据结构。这个程序构建得很好,但我遇到了这个运行时错误,到目前为止,我还没有看到问题的根源 我所了解的信息很少,问题可能是由于试图释放未使用malloc分配的内存。但在下面的代码中,我看不出这可能发生在哪里 下面是使用静态数组的堆栈的接口实现代码。我还添加了堆栈接口代码以在堆栈上添加字符,并添加了驱动程序以测试例程 #include "stack.h" #include "stdlib.

我正在为一个班写这个程序。这个程序是一个使用堆栈的简单括号检查器应用程序。在本例中,我使用了静态数组来实现堆栈数据结构。这个程序构建得很好,但我遇到了这个运行时错误,到目前为止,我还没有看到问题的根源

我所了解的信息很少,问题可能是由于试图释放未使用malloc分配的内存。但在下面的代码中,我看不出这可能发生在哪里

下面是使用静态数组的堆栈的接口实现代码。我还添加了堆栈接口代码以在堆栈上添加字符,并添加了驱动程序以测试例程

#include "stack.h"
#include "stdlib.h" /* malloc, free */
#include "stdio.h"

#define MAXSTACKSIZE 10

struct stack_record {
  generic_ptr base[MAXSTACKSIZE];
  generic_ptr * top;
};

unsigned int num_elements(stack * const p_S)
{
  unsigned int numels = ((*p_S)->top - (*p_S)->base);
  /*  return ((*p_S)->top - (*p_S)->base); */
  printf("number of elements in the stack is: %u\n", numels);
  return numels;
}
status init_stack(stack * const p_S)
{
  stack_record * record = (stack_record *)malloc(sizeof(stack_record));
  if(record == NULL) {
    return ERROR;
  }
  record->top = record->base;
  *p_S = record;
  return OK;
}
bool empty_stack(stack * const p_S)
{
  if(num_elements(p_S) == 0)
    {
      printf("stack is EMPTY!\n");
      return TRUE;
    }
  else
    {
      printf("stack NOT Empty!\n");
      return FALSE;
    }
}
status push(stack * const p_S, generic_ptr const data)
{
  if (num_elements(p_S) == MAXSTACKSIZE)
    return ERROR;

  *( (*p_S)->top ) = data;
  (*p_S)->top++;
   return OK;
}

status pop(stack * const p_S, generic_ptr * const p_data)
{
  if (empty_stack(p_S) == TRUE)
    return ERROR;
  *p_data = *((*p_S)->top);
  (*p_S)->top--;
  /*  ((*p_S)->top)--; */
  return OK;
}

status top(stack *const p_S, generic_ptr * const p_data)
{
   if (pop(p_S, p_data) == ERROR)
    return ERROR;

  return push(p_S, *p_data);
}

void destroy_stack(stack * const p_S, void (* const p_func_f)())
{
  if ((p_func_f) != NULL) {
    generic_ptr * curr;    
    for(curr = (*p_S)->top;
    curr != (*p_S)->base;
    ++curr)
          (*p_func_f)(*curr);
  }
  free(*p_S); /*free the dynamically allocated memory on the heap */
  *p_S = NULL;
 }
以下是字符的堆栈接口例程:

/*************************************************************************/
/* adapted from Esakov and Weiss, Section 5.2                            */
/*************************************************************************/

#include "char_stack.h"
#include "stdlib.h" /* malloc */
#include "stdio.h"
#define DEBUG 1 

status push_char(stack * const p_S, char const c)
{
  /*
   *     Push the character c onto the stack.
   */
  char * p_c = (char *) malloc(sizeof(char));

  if(p_c == NULL)
    return ERROR;
  *p_c = c;

  if(DEBUG)
  /* Debug code: begin */
  {
    printf("Character to PUSH on the stack: %c\n", *p_c);
  }
  /* Debug code: end */

  if (push(p_S, (generic_ptr)p_c) == ERROR) {
    if(DEBUG)
      printf("char_stack: push_char: failed to push the character on the stack!\n");
    free(p_c);
    return ERROR;
  }
  return OK;
}

status pop_char(stack * const p_S, char * const p_c)
{
  /*
   *     Pop the stack. Return the character in p_c.
   */

  generic_ptr p_data;

  if( pop(p_S, &p_data) == ERROR)
    return ERROR;

  *p_c = *((char*)p_data);

  if(DEBUG)
  /*Debug code: begin */
printf("char_stack.c::pop_char: Character to POP on the stack: %c\n", *p_c);

  /*Debug code: end */

   free(p_data);
   return OK;
}

status top_char(stack * const p_S, char * const p_c)
{
  /*
   *     Return the top character from the stack in p_c
   */
  generic_ptr p_data;

  if (top(p_S, &p_data) == ERROR)
    return ERROR;

  *p_c = *((char *)p_data); 
  return OK;
}
应用程序的驱动程序:

/**************************************************************************/
/* adapted from Esakov and Weiss, Section 5.2                             */
/**************************************************************************/

#include "stdio.h"
#include "stdlib.h"
#include "char_stack.h"

char matching_symbol(char const c)
{
  switch(c) {
    case '(': return ')';
    case ')': return '(';
    case '}': return '{';
    case '{': return '}';
    case '[': return ']';
    case ']': return '[';
  }
  return 0;
}

status consume_char(stack * const p_S, char input)
{
  switch (input) {
    case '(':
    case '{':  
    case '[':
      return push_char(p_S, input); 
    case ')':
    case '}':
    case ']':
      { 
        char c;    
        if (pop_char(p_S, &c) == ERROR || c != matching_symbol(input)) { 
          return ERROR;
        } else {
          return OK;
        }
      }
    default:
      return OK; 
  }
}

int main(int argc, char * argv[])
{

  if (argc == 1) {
    exit(EXIT_SUCCESS);
  }

  {
    stack S;

    init_stack(&S);

    {
      char *ptr;
      for (ptr = argv[1];
           *ptr != '\0' && consume_char(&S, *ptr) == OK;
           ++ptr); 
      if (*ptr == '\0' && empty_stack(&S)) { 

    destroy_stack(&S,free);
        exit(EXIT_SUCCESS);
      } else {
    destroy_stack(&S,free);
        exit(EXIT_FAILURE);
      }
    }
  }  

  exit(EXIT_SUCCESS);  
}
我想在驱动程序中补充一点,我已经缩小了对销毁堆栈的调用触发这个问题的范围。但是我已经检查了这段代码,并且相信这段代码很好,问题出在其他地方

[编辑1]:为了完整起见,我在调用这些函数的地方附加了驱动程序代码。
[编辑2]:添加了字符的堆栈接口例程。

错误消息告诉您已将值0x7b传递给
free
。如此小的数字永远不会是从
malloc
返回的内存块的地址。因此,大致上有三种可能性:

  • 您有一个完全未初始化的指针,它恰好以0x7b结束,您正在将它传递给
    free
  • 您已经从一个包含0的指针开始,将其递增0x7b,并将其传递给
    free
  • 您有一些更具创造性的内存损坏错误,该错误已将有效指针值替换为0x7b

  • 最快的解决方法是在valgrind下运行您的程序,让它告诉您这一切发生在哪里。您还可以在gdb中到处放置断点,看看您看到了什么。

    在您要传递的
    free
    函数的末尾,作为
    destroy\u stack
    的第二个参数的函数指针。这一点是为了
    释放当前在堆栈上的所有数据元素(如果还有)。但是,只有在将项目添加到堆栈时使用
    push
    函数
    malloc
    分配内存时,才允许释放此内存

    在给定的实现中,堆栈没有为项目分配内存的责任,因此它可能不应该尝试释放该内存。在这两种情况下,查找差异的地方可能是函数
    push\u char

    看起来
    push_char
    正在尝试推送一个简单的“{”字符(顺便说一句,这是
    0x7B
    ),而不是堆栈预期的由
    malloc
    创建的某个内存指针

    更新

    请记住我在上一段中所说的
    push_char
    ——问题在于
    destroy_stack
    ,这一行:

    (*p_func_f)(*curr);    /* Incorrect */
    
    curr
    是一个指针,指向为单个字符分配的一些内存(由
    push\u char
    分配),而
    *p\u func\u f
    free()
    函数。您看到问题了吗

    curr
    传递到
    *p\u func\u f
    时,取消引用是错误的。只需传递原始指针:

    (*p_func_f)(curr);     /* Correct */
    

    发现这一点的关键与我前面提到的相同:“内存地址”实际上是字符的地址{',这是存储在堆栈上的数据--这强烈表明
    free
    函数正在接收原始数据,而不是指向该数据的指针。

    我只看到函数定义。函数在哪里被调用?似乎您正在释放
    pus
    ,这是一个
    常量
    指针,并作为函数传递n参数。这也必须在程序中的其他位置释放,例如,它实际定义的位置,或作用域结束的时间。您好,谢谢您的评论。我实际上是在解引用p_以获取malloc返回的指针。这就是我传递给free的内容,以释放堆上为stack_record.sta分配的内存块ck_record包含用于存储指向char的指针的静态数组。您好,感谢您的反馈。我检查了代码并确实按下了这个应用程序的接口函数(括号检查器程序)确实使用malloc,然后将指针推到堆栈上。因此,我倾向于排除此选项。我将发布其余代码作为后续工作的一部分。@PassionProject感谢您的检查。请查看我的更新答案。感谢您的输入。实际问题是我试图释放存储在“top”中的指针。此插槽是下一个推送新项目的位置。取消引用此位置是错误的,因为它是空的!因此,出现了严重错误。我通过重写循环来修复它,使我的“curr”递减,并释放指针,直到第一个指针位于(*ps)->基本达到了。啊,我明白了。我很高兴你找到了它。PS上面for循环中的代码实际上是从
    顶部增加
    curr
    指针,而不是减少它,尽管我相信你有解决任何其他问题所需的所有信息。