C-试图使字符串小写,不断得到segfault,valgrind说地址处映射内存的权限不正确

C-试图使字符串小写,不断得到segfault,valgrind说地址处映射内存的权限不正确,c,C,这个函数给我带来了很多麻烦,我想这会比实际情况更简单 lowerString应该接受某个字符*使字符串中的所有字母都小写并返回该字符 我已经阅读了尽可能多的文章,并使用解决方案中的代码来编写代码,但我无法让它工作。我从搜索引擎的结果中查看了valgrind问题的各种答案,但我不知道出了什么问题 我想这可能是字符串文字的问题,但我只使用char* 来自头函数 char * lowerString(char *str); 从功能c: /* Makes everything in the strin

这个函数给我带来了很多麻烦,我想这会比实际情况更简单

lowerString应该接受某个字符*使字符串中的所有字母都小写并返回该字符

我已经阅读了尽可能多的文章,并使用解决方案中的代码来编写代码,但我无法让它工作。我从搜索引擎的结果中查看了valgrind问题的各种答案,但我不知道出了什么问题

我想这可能是字符串文字的问题,但我只使用char*

来自头函数

char * lowerString(char *str);
从功能c:

/* Makes everything in the string lowercase */
char * lowerString(char *str){
    char *p;
    p = str;
    for( ; *p; ++p){
        *p = tolower(atoi(p));
    }
    return p;
}
在我从b.c.运行的代码中:

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

int main(void){
    char *a, *b, *c, *p;

    a = "The cat in le Hat";
    b = "Meow meow meow meow";
    c = "This an$example12 mail@rutgers";

    p = lowerString(a);
    printf("%s\n",p);
    p = lowerString(b);
    printf("%s\n",p);
    p = lowerString(c);
    printf("%s\n",p);

    return 0;
}
为什么是atoi

 *p = tolower(atoi(p));
只需将字符转换为int

请参阅此示例: 为什么是atoi

 *p = tolower(atoi(p));
只需将字符转换为int

请参阅此示例:
问题模式是:

a = "The cat in le Hat";
p = lowerString(a);
这是一个问题,因为
a
指向常量数据,而常量数据通常是只读的,但您的
lowerString()
函数希望写入其中:

*p = tolower(atoi(p)); // Since p points to read-only memory, you crash here. 
然而,正如@cremno评论所说。。。你需要取消对p的引用<代码>*p=tolower(*p)

您需要使
指向可写内存,或者使函数返回一个新的缓冲区。例如,您可以:

a = strdup("The cat in le Hat");

然后根据需要使用
a
。如果您采用这种方法,就会意识到您刚刚分配了一个新的缓冲区,当您使用完它时必须释放它,使用
free(a)

问题模式是:

a = "The cat in le Hat";
p = lowerString(a);
这是一个问题,因为
a
指向常量数据,而常量数据通常是只读的,但您的
lowerString()
函数希望写入其中:

*p = tolower(atoi(p)); // Since p points to read-only memory, you crash here. 
然而,正如@cremno评论所说。。。你需要取消对p的引用<代码>*p=tolower(*p)

您需要使
指向可写内存,或者使函数返回一个新的缓冲区。例如,您可以:

a = strdup("The cat in le Hat");

然后根据需要使用
a
。如果您采用这种方法,就会意识到您刚刚分配了一个新的缓冲区,当您使用完它时必须释放它,使用
free(a)
a
b
c
都指向存储在潜在只读内存中的字符串文本您不能修改它们。使用
strdup*()
(或您平台上的等效项)为它们创建一个新的
char[]

a = strdup("The cat in le Hat");

 ...

free(a);

a
b
c
都指向潜在只读内存中存储的字符串文本您不能修改它们。使用
strdup*()
(或您平台上的等效项)为它们创建一个新的
char[]

a = strdup("The cat in le Hat");

 ...

free(a);


可能的副本,谢谢你的参考。这段代码将用于我必须接受char*并且必须使其小写的地方。正在尝试@mah建议立即使用strdup。可能是重复的,谢谢参考。这段代码将用于我必须接受char*并且必须使其小写的地方。正在尝试@mah suggestion立即使用strdup。我之前尝试过这个方法,但得到一个错误:从指针到不同大小的整数的转换[-Werror=pointer to int cast]*p=tolower((int)p);我可能选错了,我对这个很陌生,CIt中的第一个类必须选成
无符号字符
。不,当程序试图写入只读内存时,它是不正确的。它是无符号字符还是无符号字符*?functions.c:303:16:错误:从指针转换为不同大小的整数[-Werror=指针转换为int cast]*p=tolower((无符号字符)p);^cc1:所有警告都被视为errors@ChrisHerrera:您必须取消对指针的引用:
tolower((unsigned char)*p)
。我之前尝试过此操作,但得到一个错误:从指针转换为不同大小的整数[-Werror=pointer to int cast]*p=tolower((int)p);我可能选错了,我对这个很陌生,CIt中的第一个类必须选成
无符号字符
。不,当程序试图写入只读内存时,它是不正确的。它是无符号字符还是无符号字符*?functions.c:303:16:错误:从指针转换为不同大小的整数[-Werror=指针转换为int cast]*p=tolower((无符号字符)p);^cc1:所有警告都被视为errors@ChrisHerrera:必须取消对指针的引用:
tolower((unsigned char)*p)
。由于隐式函数声明,无法使strdup正常工作。std=c99标志将其作为一个声明(抱歉,需要几分钟才能弄清楚这一点)malloc的工作原理是否相同?试图使用strdupa
#include
来获得
strdup()的原型。如果需要,可以使用
malloc()
来分配空间,但随后需要将字符串数据复制到中,可能需要使用
strcpy()
(也需要string.h)。明白了。使用:char*p;p=malloc((strlen(str)+1)*(sizeof(char));strcpy(p,str);别忘了
free(p)完成后,避免产生内存泄漏。感谢您的帮助,我如何接受答案?>我是否应该将帖子更改为解决方案?由于隐式函数声明,无法使strdup正常工作。std=c99标志将其作为一个声明(抱歉,需要几分钟才能弄清楚这一点)malloc的工作原理是否相同?试图使用strdupa
#include
来获得
strdup()的原型。如果需要,可以使用
malloc()
来分配空间,但随后需要将字符串数据复制到中,可能需要使用
strcpy()
(也需要string.h)。明白了。使用:char*p;p=malloc((strlen(str)+1)*(sizeof(char));strcpy(p,str);别忘了
free(p)完成后,避免产生内存泄漏。感谢您的帮助,我如何接受答案?>我应该把帖子改成解决方案吗?