【问题标题】:How to convert a char array to a char pointer in C如何在C中将char数组转换为char指针
【发布时间】:2014-10-28 12:01:52
【问题描述】:

我有一段代码,它会给我一个字符数组。 我想将此数组提供给需要字符指针的函数。 当我将此数组输入函数时,当我尝试运行程序时会导致分段错误。

这很好用。

char* buffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sum>  <part>55</part>  <part>6</part>  <part>*</part></sum>";

long output = calcXML(buffer);

当我尝试创建一个数组时,它会给我一个分段错误

char buffer[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sum>  <part>55</part>  <part>6</part>  <part>*</part></sum>";

long output = calcXML(buffer);

此外,当我尝试从数组中创建一个指针时,也会发生相同的分段错误。

char buffer[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sum>  <part>55</part>  <part>6</part>  <part>*</part></sum>";
char *ptrBuffer = malloc(strlen(buffer) * sizeof(char) + 1);
ptrBuffer = &buffer[0];

long output = calcXML(ptrBuffer);

我该如何解决这个问题?

编辑: 函数calcXML(char *xml) 会将xml 参数传递给函数xmlParseDoc()。这是libxml library的函数

【问题讨论】:

  • XY 问题 - 您的问题不在于传递 var char 数组与 char 指针,而在于 calcXML 试图处理该参数。
  • 注意:sizeof(char)定义为 1。

标签: c arrays pointers


【解决方案1】:
  • 第一个有效,因为它返回字符串文字的地址。字符串文字是全局的,即保存字符的内存在程序启动时被初始化,并且位置不会改变。
  • 第二个应该可以工作,但信息太少,无法正常工作。
  • 第三个坏了,它用本地数组的地址覆盖了malloc()分配的内存。不管它应该有效,但就像在第二个情况下信息太少一样。

另外,第三种情况下malloc()调用本身是不正确的。

它将大小计算为strlen(buffer) * sizeof(char) + 1,但由于终止字符也是一个字符,因此避免为此缩放分配是没有意义的。所以,它“应该”是(strlen(buffer) + 1) * sizeof(char)。但话又说回来,sizeof (char) 始终为 1,因此缩放完全没有意义,即它应该只是 strlen(buffer) + 1。同样,代码被破坏了,因为来自malloc() 的返回值随后被立即覆盖,但仍然如此。

【讨论】:

  • 但是指针被传递到另一个函数(calcXML),而不是返回。我忽略了什么?
【解决方案2】:

没有周围的代码很难说,但由于版本 2 是合法的 C 语法,我认为您可能正在从函数返回这个数组,这意味着它在函数退出后将不复存在。取消引用指向它的指针很可能会出现段错误。这在第一种情况下不会发生,因为字符串文字是硬编码且不可变的,因此引用仍然有效。

使用第三种方法背后的想法实际上在这里也是正确的,但是您这样做是错误的。您应该分配内存,然后将snprinftstrncpymemcpy 与字符串文字结合使用,将字符串复制到缓冲区中。现在您正在丢弃指向malloced 内存的指针,这将导致泄漏。您将指针设置为自动分配数组的开头,因此一旦超出范围,取消引用指向它的指针可能会再次出现段错误,原因与版本 2 相关。

【讨论】:

  • 对于#3,strdup 就足够了!
【解决方案3】:

第一个代码将初始化buffer 以直接指向代码的text 段中的静态字符串。修改该字符串将是未定义的行为。

第二个代码将使用静态字符串的副本初始化buffer,该副本驻留在堆栈中。函数退出时副本会消失。

第三个版本不起作用 - 你永远不会将字符串的副本放在分配的缓冲区中,然后你去用在版本 2 中创建的相同的基于堆栈的副本覆盖新指针。更简单的调用就是:

char *ptrBuffer = strdup(buffer);

不要忘记在稍后的某个时间点 free() 生成的副本。

至于为什么 #2 不起作用 - 鉴于提供的详细信息,我们无法判断。这将取决于calcXML 的实现中的某些内容,或者可能取决于您的问题中省略的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    相关资源
    最近更新 更多