It's a simple code:
//file config.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
int read_server_list(char *config_file, char **servers)
{
FILE *file;
int i, status;
file = fopen(config_file, "r+");
if(file != NULL)
{
printf("File opened.\n");
status = SUCCESS;
servers = (char **) malloc(MAX_SERVERS * sizeof(char *));
if(servers == NULL)
{
printf("Memory out.\n");
status = OUT_OF_MEM;
}
else
{
for(i = 0; i < MAX_SERVERS; i++)
{
servers[i] = (char *) malloc(MAX_CHAR_LINE);
fgets(servers[i], MAX_CHAR_LINE, file);
printf("%s",servers[i]); //prints OK
}
}
fclose(file);
}
else
{
printf("Error openig the file.\n");
status = FILE_ERROR;
}
return status;
}
void cleanup_server_list(char **servers)
{
int i = 0;
do {
free( servers[i] );
servers[i++] = NULL;
} while( i < MAX_SERVERS );
free( servers );
servers = NULL;
}
and then
//file main.c
#include <stdio.h>
#include "config.h"
int main()
{
int status;
char *file = "text.txt";
char **servers;
status = read_server_list(file, servers);
cleanup_server_list(servers); // HERE I GET THE ERROR
return 0;
}
Aha. You're new to C programming. That's why you're posting to a C++ group.
> #include <stdio.h>
> #include "config.h"
>
> int main()
> {
>
> int status;
> char *file = "text.txt";
> char **servers;
> status = read_server_list(file, servers);
>
> cleanup_server_list(servers); // HERE I GET THE ERROR
>
> return 0;
> }
The 'servers' variable is uninitialized both in the call to 'read_server' and in
the call to 'cleanup_server_list'.
Why don't you use C++ instead, it helps you do cleanup etc. automatically.
Cheers & hth.,
- Alf
--
Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
No ads, and there is some C++ stuff! :-) Just going there is good. Linking
to it is even better! Thanks in advance!
Let's explain Alf's answer a bit more detailed: You should pass the
address of a pointer as second argument to read_server_list.
Replace
char **servers;
status = read_server_list(file, servers);
by
char *servers;
status = read_server_list(file, &servers);
and you'll do just fine. The difference between those two is that the
variable servers in the second version is a pointer will point to the
newly allocated memory after read_server_list has been called.
The first version will pass a pointer to a pointer to the function.
Since this pointer is not initialized, but de-referenced inside the
function, you'll get undefined behaviour (most time you'll be lucky,
but your code may produce an Access Violation from time to time).
Regards,
Stuart
In article <4b67eba4-34f4-46d6...@a7g2000yqk.googlegroups.com>,
<DerT...@web.de> wrote:
>On Mar 30, 2:03 am, ED <edym...@gmail.com> wrote:
>> Hey people... I'm new in C programing, and i'm having some problem.
>> What's wrong with the code below. I got no error compiling the file,
>> but when executing i get a *** glibc detected *** ./test: double free
>> or corruption (out): 0xbfe83468 *** error:
>>
>> It's a simple code:
>>
>> //file config.c
>>
>[snip]
>Let's explain Alf's answer a bit more detailed: You should pass the
>address of a pointer as second argument to read_server_list.
>Replace
> char **servers;
> status = read_server_list(file, servers);
>by
> char *servers;
> status = read_server_list(file, &servers);
>and you'll do just fine. The difference between those two is that the
>variable servers in the second version is a pointer will point to the
>newly allocated memory after read_server_list has been called.
>
>The first version will pass a pointer to a pointer to the function.
>Since this pointer is not initialized, but de-referenced inside the
>function, you'll get undefined behaviour (most time you'll be lucky,
>but your code may produce an Access Violation from time to time).
I'll give you another hint extremely useful for new programmers and
IMO useful for experinced programmers too:
Initialise all of your variable at decaration time especially
pointers.
So that should give:
char *servers = 0; // NULL if you prefer
// ...
FILE * pFile = 0; // NULL if you prefer
// ...
int status = -1;
Etc.
This is a very good habit to take but is unfortunately not very
popular with C programmers but will save you lots of hassle in your
life as a programmer.
Yannick
Since this is a C++ group, I recommend you ditch C and do it in C++
instead. It becomes much easier and safer:
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> servers;
std::ifstream file("text.txt");
if(file)
{
std::string server;
while(std::getline(file, server))
servers.push_back(server);
}
}