Reputation: 789
I have a problem with understanding how "char*" works in different files. For example, i have a simple CURL function that helps me sending data to other HTTP WEB SERVICES. But i also need to recieve, here is the function located in 'curlate.h' :
#include <stdio.h>
#include <curl/curl.h>
struct string
{
char * ptr;
size_t len;
};
void init_string(struct string * s)
{
s - > len = 0;
s - > ptr = malloc(s - > len + 1);
if (s - > ptr == NULL)
{
fprintf(stderr, "malloc() failed\n");
exit(EXIT_FAILURE);
}
s - > ptr[0] = '\0';
}
size_t writefunc(void * ptr, size_t size, size_t nmemb, struct string * s)
{
size_t new_len = s - > len + size * nmemb;
s - > ptr = realloc(s - > ptr, new_len + 1);
if (s - > ptr == NULL)
{
fprintf(stderr, "realloc() failed\n");
exit(EXIT_FAILURE);
}
memcpy(s - > ptr + s - > len, ptr, size * nmemb);
s - > ptr[new_len] = '\0';
s - > len = new_len;
return size * nmemb;
}
char* curlate_and_print(char url[])
{
//printf("Curlating ... %s : ",url);
CURL *curl;
CURLcode res;
struct string s;
init_string(&s);
curl = curl_easy_init();
if(curl)
{
curl_easy_setopt(curl, CURLOPT_URL, url);
/* example.com is redirected, so we tell libcurl to follow redirection */
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
{
curl_easy_strerror(res);
}
else
{
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
res = curl_easy_perform(curl);
// *** THE FUNCTION PRINTS THE RESULT HERE WITH NO PROBLEM
printf("\nCURL_STRING BEGIN\n%s\nCURL_STRING END\n", s.ptr);
free(s.ptr);
}
/* always cleanup */
curl_easy_cleanup(curl);
}
return s.ptr;
}
The script works with no problems, it is printing stuff, but i also return the value like this return s.ptr;
and i want to use this string data in main.c
.
Now, in main.c
i call the curlate_and_print
function, it is printing data, but no matter what i do, i cannot print it in main.c
!
char* content2 = curlate_and_print(link_to_curlate);
Why in the earth char* content2
is empty in main.c
? s.ptr
is not empty, it has the content result.
Here is what i have in main.c
:
if(debug >= 1) printf("Testing, curlating %s : \n",link_to_curlate);
// in content2 sa se verse output-ul din curlate_and_print(link_to_curlate);
char* content2 = curlate_and_print(link_to_curlate);
printf("\n");
printf(">%s\n",content2); // *** I GET EMPTY STRING
printf(">%s\n",content2); // *** I GET EMPTY STRING
printf(">%s\n",content2); // *** I GET EMPTY STRING
printf(">%s\n",content2); // *** I GET EMPTY STRING
printf(">%s\n",content2); // *** I GET EMPTY STRING
How can i solve this?
The problem is, i think, that i cannot understand what the char* content2 = "asdasd"
does, for me is like saying in JAVA 'String java = "asdasd";', even though i know that is a char pointer
.
Thanks.
Upvotes: 0
Views: 190
Reputation: 406
Try changing the return statement of your function to this:
return strdup(s.ptr);
This will automatically malloc the string but you do not have to worry about that. It will basically duplicate the string for you. s.ptr
is a local variable; if you want to return it make it heap-allocated and say return s->ptr
. You have to do this because s.ptr
is local, thus after the function returns, you can no longer access the stack memory pointed to by s.ptr
.
Upvotes: 1
Reputation: 11706
The problem is when you first print the string (inside curlate_and_print
), you immediately free the string buffer (the call free(s.ptr)
). After freeing it, attempts to dereference the pointer results in undefined behavior. In your case, the string appears empty.
Upvotes: 1