0

While compiling and executing the below program i am getting a warning during compilation and seg fault during execution.

Warning

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

line 17 is the call to convertString(input, &output);

attaching the debugger is can see the segfault is occuring at the below line

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;
}

Please help me where i am doing wrong.

2
  • If you are implementing a strcpy, use strlen is not a good idea. To prevent an undefined behaviour check the lenght with a max threshold or until you find a '\0'. Also beacuse each recursion re-call strlen... Commented Jun 24, 2015 at 7:35
  • 1
    a double pointer is double *; you are using pointer to char pointer Commented Jun 24, 2015 at 9:25

5 Answers 5

5

The problem is that output is not a pointer, it's an array, and using the address-of operator on an array gives you a (single) pointer to the array (in your case of type char (*)[8]). For clarification: (void *) output == (void *) &output, both the decayed pointer of the array, and the pointer to the array, are equal.

So you're not really passing a pointer to a pointer to char to the function.


Besides the above, I see no reason that the function should take a pointer to a pointer, a plain single pointer should be enough. Otherwise you will get wrong result when using output in the printf call as then output would point beyond the end of the string.

Also, you don't terminate the output string.

Sign up to request clarification or add additional context in comments.

6 Comments

@Eregrith no, because the result of a cast is a temporary.
@Quentin Yeah I thought so. What should be done by OP then? (Apart from the obvious removal of 1 star on each param)
So you're not really passing a pointer to a pointer to char to the function, but just a plain pointer to char - this is incorrect.
@Eregrith Well, to pass a pointer to a pointer to the chars, you need that second pointer to be an lvalue. So, first define it and point it at the array, then take its address.
@MaximEgorushkin Care to elaborate? Because using the address-of operator on an array gives you a pointer to the first element of the array.
|
3

You do not really need a double pointer to the output buffer here, a plain char* suffices:

#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;
}

Comments

3

Character array output has type char [sizeof( "abcdefg" ) ] that is equivalent to char[8]. So expression &output in function call

convertString(input, &output);

has type char ( * )[8] while the corresponding parameter of the function has type char **. They are incompatible types and the compiler points to this mistake.

There is no sense to declare this parameter as having type char **. It has to be declared like char *.

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

Also within the function the terminating zero is not copied from the input string to the output string. The function simply exits.

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

And it is inefficient to calculate the length of the string in each recursion. You could substitute this condition at least for

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

or

if ( *input == '\0' )

or

if ( !*input )

Also it is unclear why the function is named convertString instead of for example copyString.

Take into account that there is a common convention that string functions return pointers to strings they process. The function can be defined simpler.

Here is a demonstrative program

#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;
}

The program output is

abcdefg

Comments

-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;
}

Probably this is what you wanted to do?

Comments

-1

The issue, as aleardy pointed out by Mr. JP in his answer, is &output does not give you a char **, it gives a char (*)[8] in this case, which will decay into a char * when used as function argument.

In your case, you don't need a pointer-to-pointer to alter the contents of the memory area pointed by that pointer. A simple pointer will do. You can change

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

to

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

and other occurrences of output similarly and call it like

convertString(input, output);

that should work.

That said, you should null-terminate output to make it use as a string.

5 Comments

Are you positive that a char(*)[8] decays to a char* ? Being a pointer and not an array itself, I don't think it does.
@Quentin well, in case of a function call , I think it does, isn't it?
Nope, it doesn't. Only array names decay to pointers.
@Quentin Why use a C++ compiler for compiling C code? check this.
My bad ! I wan't paying attention there. However, turning on warnings gives, again, warning: passing argument 1 of ‘func’ from incompatible pointer type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.