tolowersegfault在尝试为返回值分配char指针时

问题描述

我正在尝试理解作为指示器的黑色巫毒魔术师,在以下情况下我无法理解。 我对getline()的第一个参数的理解很笨拙,因此我想这全都归结为它的类型,与第二个示例中的单词不同。

以下是摘录自一个函数摘要,该函数加载文件(单词词典)并逐行读取其内容。为什么tolower()在第一个示例中起作用:

int l;
size_t len = 0;
char *word = NULL;

while ((l = getline(&word,&len,fp)) != -1)
{
    for (char *p = word; *p; ++p) *p = tolower(*p);
    // Irrelevant code below
}

但是在第二个示例中,在尝试从第一个字符分配tolower()返回之后,出现了段错误

char *word = "POTATO";
for (char *p = word; *p; ++p) *p = tolower(*p);

解决方法

浏览C标准(6.4.5字符串文字)就足够了

7不确定这些数组是否有区别,只要它们的 元素具有适当的值。 如果程序尝试执行以下操作 修改这样的数组,行为是不确定的。

首先,字符串文字是具有静态存储持续时间的字符数组。

例如,在C语言中,字符串文字"POTATO"的类型为char[7]

这是一个演示程序。

#include <stdio.h>

int main(void) 
{
    printf( "sizeof( \"POTATO\" ) = %zu\n",sizeof( "POTATO" ) );
    
    return 0;
}

程序输出为

sizeof( "POTATO" ) = 7

用于表达式数组的异常例外情况(例如,用作运算符sizeof的操作数)将转换为指向其第一个元素的指针。

所以在这个声明中

char *word = "POTATO";

(仅出于说明目的)可以被重写为

char *word = &"POTATO"[0];

用作初始化程序的字符串文字将转换为指向其首个字母'P'的指针。

为避免在C ++中更改字符串文字(与C字符串文字相反)的错误,应使用常量字符数组。

因此,在C ++中,您必须编写

const char *word = "POTATO";

建议也使用限定符const在C中声明指向字符串文字的指针。

,

提出我的问题后,我决定重新检查getline()文档。 根据它,第一个参数是char ** lineptr。意味着它是指向char的指针。 更具体地说:

getline()从流中读取整行,并存储 包含文本到* lineptr

的缓冲区

由于我对双指针和一般指针的理解仍然有限,因此我决定阅读getline()的代码,试图了解正在发生的事情:

https://dev.w3.org/libwww/Library/src/vms/getline.c

这是我所了解的内容,也是我对第二个示例的更正,以免出现段错误。

char word[] = "POTATO";
for (char *p = word; *p; ++p) *p = tolower(*p);

然后试图真正理解纠正的原因,我还搜索了char数组和char指针之间的差异,并且发现并阅读了以下内容:

https://overiq.com/c-programming-101/character-array-and-character-pointer-in-c/

我了解到的是,数组的元素可以单独修改。但是chars指针(字符串文字)不能。

我认为后者可以解决,但不可能。因此,我在第二个示例中的错误。 我试图修改char指针所指向的值,但由于缺乏对Black Mojo的了解,因此遇到了段错误。

现在我了解得更多了,这次旅行很愉快。

请随时编辑或添加您的见解。