C:队列ADT数据未正确返回

时间:2013-01-23 10:19:34

标签: c string queue void-pointers

我正在为此程序运行Xcode 4.4.1。

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

测试输入:

AAA

什么行不通:

在我调用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 ¿

任何帮助表示赞赏!谢谢!

2 个答案:

答案 0 :(得分:1)

我猜这是问题所在:

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

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

答案 1 :(得分:0)

错误是因为可能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()