Solved

Error while Returning an Array of char* from Function

Posted on 2008-06-12
35
394 Views
Last Modified: 2011-04-14
Hello,

i want to implement a function, which returns a array of char* with well formated IPs from an DNS-Lookedup Hostname.
I created the attached code and get the following warnings while compiling.
The Array needs to be dynamical because the count of IPs returned by the DNS Lookup is not known at compile-time.
Can anyone help to solve the warnings?

In function âgetipâ:
warning: assignment makes integer from pointer without a cast
warning: passing argument 1 of âsprintfâ makes pointer from integer without a cast
warning: assignment makes integer from pointer without a cast
warning: passing argument 1 of âstrcpyâ makes pointer from integer without a cast

char *getip(char *dnsname)

{

struct hostent *hostinfo;
 

if (hostinfo = gethostbyname (dnsname))

{

        printf ("Address length:     %d\n", hostinfo->h_length);
 

int ips=0;
 

while (hostinfo->h_addr_list[ips]!=NULL)

ips++;
 

char *ergebnis = (char *)malloc( ips * sizeof( char ) );
 

int i;

while (hostinfo->h_addr_list[i]!=NULL)

{

ergebnis[i]=malloc(16);

sprintf(ergebnis[i],"%d.%d.%d.%d",(unsigned char)hostinfo->h_addr_list[i][0],\

                                    (unsigned char)hostinfo->h_addr_list[i][1],\

                                    (unsigned char)hostinfo->h_addr_list[i][2],\

                                    (unsigned char)hostinfo->h_addr_list[i][3]);

i++;

}

return ergebnis;

} else

{

char *ergebnis = (char *)malloc( sizeof( char ) );

ergebnis[0]=malloc(6);

strcpy(ergebnis[0],"failed");

return ergebnis;

}

}

Open in new window

0
Comment
Question by:ktd85
  • 16
  • 12
  • 7
35 Comments
 
LVL 40

Accepted Solution

by:
evilrix earned 220 total points
ID: 21768467
Your heap allocated array has the wrong signature. You care creating an array of char not char *

char *ergebnis = (char *)malloc( ips * sizeof( char ) );

Should be something like...

char **ergebnis = malloc( ips * sizeof( char *) );

Note, you don't need to car the return of malloc in C since it is a void * it will automatically convert to any pointer type.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21768472
>> you don't need to car the return of malloc
Typo: you don't need to cast the return of malloc
0
 
LVL 2

Author Comment

by:ktd85
ID: 21768503
thanks for your Quick response.

Now my code looks like below and now i get the following warnings:
warning: assignment makes integer from pointer without a cast
warning: passing argument 1 of âstrcpyâ makes pointer from integer without a cast

void *getip(char *dnsname)

{

struct hostent *hostinfo;
 

if (hostinfo = gethostbyname (dnsname))

{

        printf ("Address length:     %d\n", hostinfo->h_length);
 

int ips=0;
 

while (hostinfo->h_addr_list[ips]!=NULL)

ips++;
 

char **ergebnis = malloc( ips * sizeof( char *) );

//char *ergebnis = (char *)malloc( ips * sizeof( char ) );
 

int i;

while (hostinfo->h_addr_list[i]!=NULL)

{

ergebnis[i]=malloc(16);

sprintf(ergebnis[i],"%d.%d.%d.%d",(unsigned char)hostinfo->h_addr_list[i][0],\

                                    (unsigned char)hostinfo->h_addr_list[i][1],\

                                    (unsigned char)hostinfo->h_addr_list[i][2],\

                                    (unsigned char)hostinfo->h_addr_list[i][3]);

i++;

}

return ergebnis;

} else

{

char *ergebnis = (char *)malloc( sizeof( char ) );

ergebnis[0]=malloc(6);

strcpy(ergebnis[0],"failed");

return ergebnis;

}

}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 21768516
You didn't change line 30

char *ergebnis = (char *)malloc( sizeof( char ) );

:)
0
 
LVL 2

Author Comment

by:ktd85
ID: 21768614
Hi,

i changed the code to the following.
The errors are gone.
But how to access the result of the function?
void *getip(char *dnsname)

{

struct hostent *hostinfo;
 

if (hostinfo = gethostbyname (dnsname))

{

        printf ("Address length:     %d\n", hostinfo->h_length);
 

int ips=0;
 

while (hostinfo->h_addr_list[ips]!=NULL)

ips++;
 

char **ergebnis = malloc( ips * sizeof( char *) );
 

//char *ergebnis = (char *)malloc( ips* sizeof( char ) );
 

int i;

while (hostinfo->h_addr_list[i]!=NULL)

{

ergebnis[i]=malloc(16);

sprintf(ergebnis[i],"%d.%d.%d.%d",(unsigned char)hostinfo->h_addr_list[i][0],\

                                    (unsigned char)hostinfo->h_addr_list[i][1],\

                                    (unsigned char)hostinfo->h_addr_list[i][2],\

                                    (unsigned char)hostinfo->h_addr_list[i][3]);

i++;

}

return ergebnis;

} else

{

char **ergebnis = malloc( sizeof( char ) );

ergebnis[0]=malloc(6);

strcpy(ergebnis[0],"failed");

return ergebnis;

}

}

Open in new window

0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 220 total points
ID: 21768659
BTW: Shouldn't the function return char ** too?

>> But how to access the result of the function?
I don't get what you mean. DO you mean something like this...?

char ** ppErgebnis = char **getip(char *dnsname);

char * pErgebnis1 = ppErgebnis[0];
char * pErgebnis2 = ppErgebnis[2];
...
char * pErgebnisN = ppErgebnis[N]; // Where N is the last element in the array

0
 
LVL 2

Author Comment

by:ktd85
ID: 21769403
Thanks for the example how to get access to the functions return value.

But now the Call of the function results in a segmentation fault.

My actual Function code attached.
char **getip(char *dnsname)

{

struct hostent *hostinfo;
 

if (hostinfo = gethostbyname (dnsname))

{

        printf ("Address length:     %d\n", hostinfo->h_length);
 

int ips=0;
 

while (hostinfo->h_addr_list[ips]!=NULL)

ips++;
 

char **ergebnis = malloc( ips * sizeof( char *) );
 

int i;

while (hostinfo->h_addr_list[i]!=NULL)

{

ergebnis[i]=malloc(16);

sprintf(ergebnis[i],"%d.%d.%d.%d",(unsigned char)hostinfo->h_addr_list[i][0],\

                                    (unsigned char)hostinfo->h_addr_list[i][1],\

                                    (unsigned char)hostinfo->h_addr_list[i][2],\

                                    (unsigned char)hostinfo->h_addr_list[i][3]);

printf("%s\n",ergebnis[i]);

i++;

}

return ergebnis;

} else

{

char **ergebnis = malloc( sizeof( char ) );

ergebnis[0]=malloc(6);

strcpy(ergebnis[0],"failed");

return ergebnis;

}

}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 21769450
Can you post all your code (or at least a working example that generates the problem please? I suspect you are trying to read beyond the end of the returned array.
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 30 total points
ID: 21769538
>> int i;

You should always initialize variables (in this case to 0)


>> char **ergebnis = malloc( sizeof( char ) );

You don't want to allocate just one byte of memory (sizeof(char)). You want to allocate enough room for a char*, so use sizeof(char*)


>> ergebnis[0]=malloc(6);
>> strcpy(ergebnis[0],"failed");

The string "failed" needs 7 characters (6 + 1 for the trailing null), so use malloc(7).


All of these problems can cause a segmentation fault or other type of crash.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21769568
>> You don't want to allocate just one byte of memory (sizeof(char)).
Argg... well spotted -- I've already pointed that out twice :)

>> The string "failed" needs 7 characters (6 + 1 for the trailing null), so use malloc(7).
Again, good spot :)
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21769587
;)
0
 
LVL 2

Author Comment

by:ktd85
ID: 21769644
Thank you very very much.
After correcting the issues you pointed out the function is working fine. The working source code is attached.

The following code is used to call and test the function:
        char **ppErgebnis=getip("www.google.de");
        printf ("%s\n%s\n%s",ppErgebnis[0],ppErgebnis[1],ppErgebnis[2]);
 
BTW: What about the Memory allocted should i call free(ppErgebnis) after processing the output?
char **getip(char *dnsname)

{

struct hostent *hostinfo;
 

if (hostinfo = gethostbyname (dnsname))

{

        printf ("Address length:     %d\n", hostinfo->h_length);
 

int ips=0;
 

while (hostinfo->h_addr_list[ips]!=NULL)

ips++;
 

char **ergebnis = malloc( ips * sizeof( char *) );
 

int i=0;

while (hostinfo->h_addr_list[i]!=NULL)

{

ergebnis[i]=malloc(16);

sprintf(ergebnis[i],"%d.%d.%d.%d",(unsigned char)hostinfo->h_addr_list[i][0],\

                                    (unsigned char)hostinfo->h_addr_list[i][1],\

                                    (unsigned char)hostinfo->h_addr_list[i][2],\

                                    (unsigned char)hostinfo->h_addr_list[i][3]);

i++;

}

return ergebnis;

} else

{

char **ergebnis = malloc( sizeof( char*) );

ergebnis[0]=malloc(7);

strcpy(ergebnis[0],"failed");

return ergebnis;

}

}

Open in new window

0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 220 total points
ID: 21769670
>> What about the Memory allocted should i call free(ppErgebnis) after processing the output?
You need to free it and all the elements it contains since they too are also allocated by malloc, right?

char **ergebnis = malloc( ips * sizeof( char *) );
ergebnis[i]=malloc(16);

So you need to free ergebnis[i] first and then ergebnis.

Make sense?
0
 
LVL 2

Author Comment

by:ktd85
ID: 21769687
Should i freed it inside the function?
Can the result be accessed by the procedure calling that function?
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21769747
>> Should i freed it inside the function?
Well you can't if you want to use it outside the function.

>> Can the result be accessed by the procedure calling that function?
Not if you free it. You'll have to do this outside of the function.
0
 
LVL 2

Author Comment

by:ktd85
ID: 21769822
Thanks thats what i wanted to know.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21769850
>> Thanks thats what i wanted to know.
No worries :)
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 40

Expert Comment

by:evilrix
ID: 21769903
ktd85,

Any reason you've asked for the Q to be closed in 7 days? Are you unhappy with the answers given?

If you'd like to finalize this question now you can accept those answers (note you can accept more than one answer) that helped you and apportion the points as you see fit. If you are unsure the help will guide you: http://www.experts-exchange.com/help.jsp#hi331 If you are still unsure please post back here and either myself or Infinity08 will be happy to assist you.

Alternatively, if you'd like to receive help from a moderator please click the link on the top right of this page (just below your question text) labeled 'Report Abuse" and this will bring this thread to their attention and they will be only too happy to guide you.

Thanks.

-Rx.

0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21769921
Make sure you free all data correctly ... ie. every malloc has to have a corresponding free (so, free ergebnis[i] for every i in a loop, and then free ergebnis).

Btw :

>>         printf ("%s\n%s\n%s",ppErgebnis[0],ppErgebnis[1],ppErgebnis[2]);

Make sure that the function actually returned 3 strings, before trying to print 3. If it returned less, then this might cause another segmentation fault or worse.

In other words, you might want to change the signature of your function to include the size ...
0
 
LVL 2

Author Comment

by:ktd85
ID: 21769927
Sorry i faild closing the question.
The answers were all fine don't worrie.

I think I've corrected the issue right now.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21769951
That's ok, ktd85 :) All's fine !
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21769960
>> Sorry i faild closing the question.
No worries, just wanted to make sure you had all you needed :)

>> The answers were all fine don't worrie.
Good stuff

>> I think I've corrected the issue right now.
Indeed you have, many thanks.
0
 
LVL 2

Author Comment

by:ktd85
ID: 21770077
Sorry to bother you again.
As i tried to implement a method that displays the returned values it failed again in segmentation fault.

Code attached below.
void printarray(char **ppErgebnis)

{

int i=0;

if (ppErgebnis!=NULL)

while (ppErgebnis[i]!=NULL)

 {

   printf("%s\n",ppErgebnis[i]);

   i++;

 }

}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 21770164
>> while (ppErgebnis[i]!=NULL)
This test assumes that at some point you'll hit a NULL within the bounds of the array ppErgebnis. Do you ensure when you create ppErgebnis you initialize the unused elements to NULL and there will always be at least one set to NULL?
0
 
LVL 2

Author Comment

by:ktd85
ID: 21770294
No, that was the point! Thanks.
0
 
LVL 2

Author Comment

by:ktd85
ID: 21770361
Would it statisfy the requirements if i change the line allocations space for the list:
char **ergebnis = malloc( (ips+1) * sizeof( char *) );

and add the following line at the end of the while-loop?
ergebnis[i+1]=NULL;

Because i changed this and get a segmentation fault...

Is there any console-based ide under debian which can handle breakpoints?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21770529
>> char **ergebnis = malloc( (ips+1) * sizeof( char *) );

Yes.


>> and add the following line at the end of the while-loop?
>> ergebnis[i+1]=NULL;

i has already been incremented - you don't need to increment it again, so :

        ergebnis[i] = NULL;

or even :

        ergebnis[ips] = NULL;
0
 
LVL 2

Author Comment

by:ktd85
ID: 21770585
Thanks.
Sorry for asking so stupid questions...
Do you thing it would be easier if i move to c++?
What about the compatibility of C code to C++ code?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21770714
>> Do you thing it would be easier if i move to c++?

It could be if you use a vector of strings for example ...


>> What about the compatibility of C code to C++ code?

C code will be accepted by a compliant C++ compiler.
0
 
LVL 2

Author Comment

by:ktd85
ID: 21770813
Is g++ a compliant compiler?
Is there any console-based ide under debian which can handle breakpoints?
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21770852
Sorry, I had to drive home -- I see I8 has been very helpful though :)

>> Is there any console-based ide under debian which can handle breakpoints?
Try ddd
http://www.gnu.org/software/ddd/


>> C code will be accepted by a compliant C++ compiler
Sorry to disagree -- MOST but not all C code will be accepted. For example, in C++ you have to cast your void * in C you don't.

/* Works in C but not C++ */

int main()

{

	void * pv = 0;

	int * pi = pv;
 

	return 0;

}

Open in new window

0
 
LVL 40

Expert Comment

by:evilrix
ID: 21770869
>>>> Is there any console-based ide under debian which can handle breakpoints?
>>Try ddd

Sorry, I've just re-read the Q and saw the word console -- missed it last time!  :)

Try gdb
http://www.gnu.org/software/gdb/
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21770879
^^^ BTW: It's not an IDE it's a debugger -- what is wrong with me today :)
0
 
LVL 40

Expert Comment

by:evilrix
ID: 21770900
>> Is g++ a compliant compiler?
Complaint with the C++ standard? Truth is, very few are 100% compliant but gcc (especially from 4.x onwards) does a very good job of coming close. Certainly more so than Microsoft's compiler.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 21773852
>> >> C code will be accepted by a compliant C++ compiler
>> Sorry to disagree -- MOST but not all C code will be accepted.

True - there's no 100% compatibility, mostly due to C++'s type safety. I should have been more precise and said "Good C code will be accepted by a compliant C++ compiler" ;)

In any case, C code should be very easy to "port" to a C++ compiler ... just watch the warnings and errors the compiler throws out, and add explicit casts etc. wherever needed.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now