Link to home
Start Free TrialLog in
Avatar of ktd85
ktd85

asked on

Error while Returning an Array of char* from Function

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

ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> you don't need to car the return of malloc
Typo: you don't need to cast the return of malloc
Avatar of ktd85
ktd85

ASKER

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

You didn't change line 30

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

:)
Avatar of ktd85

ASKER

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

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ktd85

ASKER

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

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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> 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 :)
Avatar of ktd85

ASKER

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

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ktd85

ASKER

Should i freed it inside the function?
Can the result be accessed by the procedure calling that function?
>> 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.
Avatar of ktd85

ASKER

Thanks thats what i wanted to know.
>> Thanks thats what i wanted to know.
No worries :)
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: https://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.

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 ...
Avatar of ktd85

ASKER

Sorry i faild closing the question.
The answers were all fine don't worrie.

I think I've corrected the issue right now.
That's ok, ktd85 :) All's fine !
>> 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.
Avatar of ktd85

ASKER

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

>> 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?
Avatar of ktd85

ASKER

No, that was the point! Thanks.
Avatar of ktd85

ASKER

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?
>> 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;
Avatar of ktd85

ASKER

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?
>> 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.
Avatar of ktd85

ASKER

Is g++ a compliant compiler?
Is there any console-based ide under debian which can handle breakpoints?
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

>>>> 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/
^^^ BTW: It's not an IDE it's a debugger -- what is wrong with me today :)
>> 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.
>> >> 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.