使用指向char的指针时出现分段错误

时间:2015-06-24 07:22:53

标签: c pointers char segmentation-fault

在编译和执行以下程序时,我在编译期间收到警告,并在执行期间发生seg错误。

警告

program.c: In function main:
program.c:17: warning: passing argument 2 of convertString from incompatible pointer type

第17行是对convertString(input, &output);

的调用

附加调试器可以看到在下面的行中发生了段错误

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400521 in convertString (input=0x7fffffffd100 "abcdefg", output=0x7fffffffd0f0) at program.c:9
9           **output = *input;
(gdb) s

#include<stdio.h>
#include<string.h>
void convertString(char *input, char **output)
{
    if(strlen(input)== 0)
    {
        return;
    }
    **output = *input;
    (*output)++;
    convertString(input+1,output);
}
int main()
{
    char input[] = "abcdefg";
    char output[sizeof(input)];
    convertString(input, &output);
    printf("%s", output);
    return 0;
}

请帮助我在哪里做错了。

5 个答案:

答案 0 :(得分:5)

问题是output不是指针,它是一个数组,并且在数组上使用address-of运算符为您提供了一个指向数组的(单个)指针(在您的类型{{1]的情况下}})。为了澄清:char (*)[8],数组的衰减指针和指向数组的指针都是相等的。

所以你并没有真正地将指针传递给指向(void *) output == (void *) &output函数的指针。

除了上面的内容之外,我认为函数不应该使用指向指针的指针,普通的单指针就足够了。否则,在char调用中使用output时会出现错误结果,因为printf会超出字符串的结尾。

此外,您不会终止output字符串。

答案 1 :(得分:3)

这里你真的不需要一个指向输出缓冲区的双指针,一个普通的char*就足够了:

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

void convertString(char *input, char *output)
{
    if(!(*output = *input)) // Copy the zero terminator as well.
        return;
    convertString(input + 1, output + 1);
}

int main()
{
    char input[] = "abcdefg";
    char output[sizeof(input)];
    convertString(input, output);
    printf("%s", output);
    return 0;
}

答案 2 :(得分:3)

字符数组output的类型char [sizeof( "abcdefg" ) ]等同于char[8]。所以在函数调用中表达&output

convertString(input, &output);

具有类型char ( * )[8],而函数的相应参数具有类型char **。它们是不兼容的类型,编译器指出了这个错误。

将此参数声明为类型char **是没有意义的。它必须声明为char *

void convertString(char *input, char *output);

同样在函数内,终止零不会从输入字符串复制到输出字符串。该功能只是退出。

if(strlen(input)== 0)
{
    return;
}

在每次递归中计算字符串的长度是低效的。您至少可以替换此条件

if ( input[0] == '\0' )

if ( *input == '\0' )

if ( !*input )

还不清楚为什么函数名为convertString而不是copyString

考虑到一个常见的约定,即字符串函数返回指向它们处理的字符串的指针。 可以更简单地定义函数。

这是一个示范程序

#include <stdio.h>

char * copyString( char *output, const char *input )
{
    if ( ( *output = *input ) ) copyString( output + 1, input + 1 );
    return output;
}

int main(void) 
{
    char input[] = "abcdefg";
    char output[sizeof(input)];

    puts( copyString( output, input ) );    

    return 0;
}

程序输出

abcdefg

答案 3 :(得分:-1)

正如Mr. JP his answerdocs所指出的那样,问题是&output char **没有给你char (*)[8],它给出了char * case,当用作函数参数时将衰减为void convertString(char *input, char **output)

在您的情况下,您不需要指向指针来改变该指针指向的内存区域的内容。一个简单的指针就可以了。你可以改变

void convertString(char *input, char *output)  //output is of type char*

output

convertString(input, output); 的其他事件类似,并将其称为

output

应该有用。

也就是说,你应该将normed空终止,使其用作字符串

答案 4 :(得分:-1)

#include<stdio.h>
#include<string.h>
void convertString(char *input, char *output)
{
    if(strlen(input)== 0)
    {
        return;
    }
    *output = *input;
    output++;
    convertString(input+1,output);
}
int main()
{
    char input[] = "abcdefg";
    char output[sizeof(input)];
    convertString(input, output);
    printf("%s\n", output);
    return 0;
}

这可能是你想做的?