将char *转换为大写段错误

时间:2016-02-04 19:43:50

标签: c string pointers segmentation-fault

我有一个简单的程序,我有一个外部写的字符串(在这个snippit的情况下,它是用户创建的)。我正试图将其某些部分资本化。

我首先使用分隔符来定位它,并尝试使用toupper函数对其进行大写,但是我似乎正在使用segfaults来完成它。运行valgrind不会提供任何错误,只是说明:

Process terminating with default action of signal 11 (SIGSEGV)
==10180==  Bad permissions for mapped region at address 0x4007B9

代码:

int main(void) {
    char * test;

    char * f;
    char * s;
    char * p;

    test = "first:second:third:fourth:";
    f = strtok(test,":");


    for(p = f; *p; *p = toupper(*p), p++); //segfaults

    printf("f is %s \n",f); //this should print "FIRST" as it should be capitalized

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您不能在字符串文字上使用strtok(),因为它会修改它的参数,并且您无法修改字符串文字。

你也不能在这个循环中修改它

for (p = f; *p; *p = toupper(*p), p++); //segfaults

你需要一个数组或一个动态分配的内存块,这两个内存都是可写的,你可以使用像这样的字符串文字初始化的数组

char array[] = "This is a string literal, you are not allowed to modify it";
/* Now the arest of the code could work but ... */

如果找不到您要查找的内容,还需要检查strtok() NULL的返回值。

使用malloc()你也可以这样做

cosnt char *string_literal = "This is a sample string";
size_t length = strlen(string_literal);
char *buffer = malloc(length + 1);
if (buffer == NULL)
    return -1; // Allocation failure.
memcpy(buffer, string_literal, length + 1);
//                                      ^ copy the null terminator too
// Process your newly allocated copy here and,
free(buffer);

注意:关于原始代码

f = s = p = test = malloc(sizeof(char * ) * 10);

malloc()不用作通用初始化函数,它用于获取可以在程序中使用的内存指针,可以从/向它读/写。当您使用malloc()请求内存时,您需要在程序中使用特定的(通常精确的)字节数。

如果返回的指针不是NULL,则可以使用它,如果出现错误或系统内存不足,它将返回NULL

您的代码存在一个主要问题,因为所有指针fsptest都指向相同的内存地址,也因为您分配了任意大小这可能是你想要/不需要的那个。

当你free(f)然后继续free(s)时,你正在释放两次相同的指针而你实际上做的不止于此。在同一个poitner上调用free()两次会调用未定义的行为。