在 C 中连接字符串的未定义行为

Jon*_* S. 1 c pointers c-strings string-concatenation function-definition

我正在编写一个 C 程序,该程序将连接所有行(\n包括“ ”),同时将指针保存到最终字符串的最后一个字符。但是,我没有得到我预期的结果。可能是什么问题呢?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node {
  struct Node *next;
  struct Node *prev;
};

struct Node *CreateNewNode() {
  struct Node *newNode = malloc(sizeof(struct Node));
  return newNode;
}

struct PieceTable {
  char *buffer;
  char *ptr_to_last_character;
} PT;

void strconcatenate(char *source) {
  size_t source_len = strlen(source);
  size_t buffer_len = strlen(PT.buffer);
  PT.buffer = realloc(PT.buffer, buffer_len + source_len + 1);
  while (*source)
    *PT.ptr_to_last_character++ = *source++;
  *PT.ptr_to_last_character = '\0';
}

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

  char input_line[1024];

  PT.buffer = malloc(sizeof(char) * 2);
  *PT.buffer = '\0';
  PT.ptr_to_last_character = PT.buffer;

  struct Node *new_node = CreateNewNode();
  new_node->next = NULL;
  new_node->prev = NULL;

  strconcatenate("Lorem ipsum\n");
  strconcatenate("dolor sit amet\n");
  strconcatenate("consectetur adipiscing elit\n");

  printf("%s", PT.buffer);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

预期输出:

Lorem ipsum
dolor sit amet
consectetur adipiscing elit
Run Code Online (Sandbox Code Playgroud)

输出:

etur adipiscing elit
Run Code Online (Sandbox Code Playgroud)

Pau*_*kin 5

你重新分配PT.buffer,但你不更新PT.ptr_to_last_character。当realloc不能仅扩展当前分配而是在不同地址返回一个新的更大区域时,这会导致未定义的行为,从而ptr_to_last_character指向旧内存。

可能更好的是存储缓冲区的长度而不是指向最后一个字符的指针,这样您就不必担心使其无效。