【问题标题】:C: Queue ADT data not returning correctlyC:队列 ADT 数据未正确返回
【发布时间】:2013-01-06 18:54:35
【问题描述】:

我正在为这个程序运行 Xcode 4.4.1。

对象: 调用enqueue将用户输入的字符串插入队列,调用dequeue取出插入的字符串。

测试输入:

啊啊

什么不起作用:

在我调用dequeue(queue, &name) 的那一行,我期望得到 aaa 的出列值。但是,我得到一个垃圾或 NULL 值。

// 原型声明

int    enqueue     ( QUEUE *queue, void * dataInPtr );  // returns success
int    dequeue     ( QUEUE *queue, void **dataOutPtr ); // returns success
bool processQueue(QUEUE *queue, bool flag);

// 函数定义(仅显示processQueue

bool processQueue(QUEUE *queue, bool flag) {
  char *name;
  char usInput[MAX_LENGTH_INPUT + 1];
  int success;

  if(ENQUEUE == flag) {
    do {
      printf("Enter 3 letters for name: ");
      fscanf(stdin, "%s", usInput);
    } while(!validateInputName(usInput));

    name = malloc(sizeof *name * 4);
    name = usInput;
    printf("usInput==\"%s\" and name==\"%s\"\n", usInput); // correctly shown   
    return enqueue(queue, name);
  } else { // DEQUEUE == flag
    if (!emptyQueue(queue)) {
      dequeue(queue, &name); // I assume I have problem here??
      printf("dequeued name == \"%s\"\n", name); // incorrectly shown. why???
    // TODO: free(name);
      return true;
    } else {
      return false;
    }
  }
}

// 输出:

usInput=="aaa" and name=="aaa"
dequeued name == "¿" // here, I am expecting aaa, not ¿

感谢任何帮助!谢谢!

【问题讨论】:

  • malloc(sizeof *name); 等价于malloc(1)
  • 我刚刚把它改成了name = malloc(sizeof *name * 4);。它仍然返回 ¿(不正确的值)。

标签: c string queue void-pointers


【解决方案1】:

错误是因为enqueue() 可能会获取一个指向字符串的指针并将其存储在队列中。在声明中:

name = usInput;

您将传递给enqueue() 的指针替换为指向自动存储数组开头的指针;那是函数终止后无效的存储,这就是您看到垃圾的原因。存储/使用指向已释放内存的指针会调用未定义的行为。

您似乎对动态内存分配和字符串复制感到困惑。这是您可以处理的一种方法:

/* First, allocate enough memory. Let's say 12 bytes is enough. */
name = malloc(12);
/* We'll need to copy our string to the memory we allocated and truncate it to 12 bytes */
if (snprintf(name, 12, "%s", usInput) < 0) {
    printf("Output error encountered by snprintf\n");
    return -1; /* error value */
}
/* Now enqueue NAME assuming that enqueue() does not copy it. */
return enqueue(queue, name);

注意:

  1. 始终检查错误。
  2. 始终设置最大输入大小。
  3. 不要泄漏内存 - free() 你是什么 malloc()

【讨论】:

    【解决方案2】:

    我猜这是问题所在:

    name = malloc(sizeof *name * 4);
    name = usInput;
    

    通过将 name 重置为指向临时的 usInput,您将 (a) 泄漏内存并 (b) 导致未定义的行为。

    【讨论】:

    • 哦,我明白了。那么,我应该使用malloc 吗?解决方法是什么?
    • 解决方法是 strcpy(name,input); 或省略 malloc() 而只使用 name=stdup(input);
    猜你喜欢
    • 2018-12-31
    • 2017-06-17
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多