C basics, string to pointer - c

I have project with 3 files.
Common header contain function declaration for check mysql connection:
int conn_check(char **m_error);
Main file calls function and expect some message in m_error in case of error:
if (!conn_check(&m_error)==0)
{
printf("%s\n", m_error);
}
And now function in which I have problem because weak knowing of pointers:
int conn_check(char **m_error)
{
int retval = 0;
char mysqlerror[255] = {0};
MYSQL *conn;
conn = mysql_init(NULL);
if (conn)
{
if (mysql_real_connect(conn, mysql_server, mysql_user_name, mysql_password, "", (ulong)mysql_serverport, mysql_socket, 0)==NULL)
{
sprintf(mysqlerror, "%u: %s", mysql_errno(conn), mysql_error(conn));
*m_error = mysqlerror; // Problem here
retval = -1;
}
} else retval = -2;
mysql_close(conn);
return retval;
}
Question is how to properly assign string mysqlerror to char pointer m_error so error message can be printed through printf in main.

char **m_error means you're passing a pointer to a pointer. Presumably this is because the function already returns an int and you want to also have the text of the error. As it is, you're assigning the address of a stack variable to the pointer which you can not do.
You would need to allocate memory, assign it to the pointer, then write to it:
*m_error = calloc(255, sizeof(char));
snprintf(*m_error, 255, "%u: %s", mysql_errno(conn), mysql_error(conn));
vasprintf() will do all of it for you:
vasprintf(m_error, "%u: %s", mysql_errno(conn), mysql_error(conn));
Note that you would then need to free() this back in the calling function.

You are returning a pointer to a local variable (char mysqlerror[255]). You should define mysqlerror in your main file and call your function like:
if (!conn_check(mysqlerror)==0)
and change the prototype:
int conn_check(char *mysqlerror)
and remove lines:
char mysqlerror[255] = {0};
*m_error = mysqlerror;

Here would be my solution:
char m_error[255];
if (!conn_check(&m_error)==0)
{
printf("%s\n", m_error);
}
int conn_check(char **m_error)
{
int retval = 0;
char mysqlerror[255];
MYSQL *conn;
...
sprintf(mysqlerror, "%u: %s", mysql_errno(conn), mysql_error(conn));
strcopy(*m_error, mysqlerror);
retval = -1;
...
}

Upon return from conn_check(), if you do the *m_error = mysqlerror; line, you'll end up with a quite possibly invalid pointer by then, as the local char array mysqlerror is not valid outside of the local function.
You'll need to pass in a pointer to a buffer and copy the string in, or duplicate the string using strdup to allocate some global memory to give you a valid pointer for returning (but if you do this, don't forget to free the memory in main() using free afterwards).
EDIT: If you choose to pass in a buffer, it's also good practice to pass in the max buffer size, so when you copy your string in, you don't overflow the buffer.
EDIT 2: A very hacky way of fixing your existing code with minimum code is of course to declare mysqlerror as static, so it is valid outside of the function. I wouldn't ever recommend doing that though, as it means the function wouldn't be thread-safe.

Related

How to correctly free a structure returned from a function?

I'm new to C and trying to figure out how to dispose of the structures, references to which are returned from a function.
For example, this is roughly what I want to do.
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test);
return 0;
}
So in main I get the test struct. After printf (assume that there is some code after wards) I no longer need it and want to deallocate it. But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
A structure can be deallocated just like any other pointer. You however have to ensure that all its allocated members are freed before doing so (failing to do so would most likely result in a memory leak of the members of your structure).
typedef struct test_t{
char *test_c;
} test_t;
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
char* buf = malloc(sizeof(char) * 5);
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
int main() {
test_t* test;
testFunc(&test);
printf("%s\n",test->test_c);
free(test->test_c);
free(test);
return 0;
}
In case your structure doesn't allocate all of its elements, you can set their pointer to NULL, which once passed to free (3) would be equivalent to doing nothing.
But how to do it properly? Should I just deallocate test_c explicitly first? But what if it wasn't allocated?
Basic rule of thumb: if you write a function that allocates a resource, write a complementary one that deallocates it. So when applied to your example:
void testFree(test_t* toFree) {
free(toFree->test_c);
free(toFree);
}
... and then ...
printf("%s\n",test->test_c);
testFree(test);
If testFree is implemented and exposed along with testFunc, the callers don't need to know your implementation details. The functions themselves, being part of the same library, will make sure the invariants are maintained properly. Should you ever switch allocation schemes, no calling code needs to change. You would just modify testFree to go along with the new testFunc and re-link.
First, you'll need to free the memory you,ve allocated for the char in the struct given that you have initialized it. Otherwise, you'll get an error so before any free instruction you should check whether the pointer that holds the memory position for test_p you're trying to free isn't NULL. Besides, the free instruction should take *test as a parameter instead of test.
You should have a procedure which allocates and initializes an instance of test_t. In C++ or other object-oriented languages this would be a constructor. In C you have to roll your own - something similar to the following:
test_t *create_test_t(char *init_test_c)
{
test_t *tt;
tt = malloc(sizeof(test_t));
if(init_test_c != NULL)
{
tt->test_c = malloc(strlen(init_test_c)+1);
strcpy(tt->test_c, init_test_c);
}
else
tt->test_c = NULL;
}
You'll also want a function to get rid of a test_t instance correctly. Something like:
void destroy_test_t(test_t *tt, bool static)
{
free(tt->test_c);
if(!static)
free(tt);
}
The static parameter is included to control whether tt should or should not be free'd. Obviously you don't want to attempt to free a pointer to a static instance of test_t, in which case you'd pass TRUE for static. For dynamically-allocated instances of test_t, e.g. those created using the create_test_t procedure, you'd pass FALSE for static.
You then use these functions every time you need to create or destroy a test_t.
Best of luck.
Should I just deallocate test_c explicitly first?
Yes, you have to free test_c first, because, if you free test, you will lose the reference to test_c.
But what if it wasn't allocated?
As you are returning int from testFunc, you can use it as a state of the allocation of your structure (although, returning a pointer would be a better idea IMHO):
int testFunc(test_t** output){
test_t* testStruct = malloc(sizeof(testStruct));
if (testStruct == NULL)
/* testStruct allocation failure. */
return -1;
char* buf = malloc(sizeof(char) * 5);
if (buf == NULL) {
/* buf allocation failure. */
free(testStruct);
return -1;
}
strcpy(buf, "test");
testStruct->test_c = buf;
*output = testStruct;
return 0;
}
After that, you check testFunc failure:
/* Check for allocation failure. */
if (testFunc(&test) == -1) {
fprintf(stderr, "Allocation error");
exit(EXIT_FAILURE);
}
/* Allocation succeeded. */
printf("%s\n",test->test_c);
free(test->test_c);
free(test)

Keeping the value of a String initialized into a function

I know my title isn't clear, It will be clearer with code + examples.
I want to initialize a char* ("motSecret" in the main, "mot" in my function) containing a word selected randomly into a file, doing this into a function. This array is made dynamic using memory allocation.
The variable in my function get well initialized, but when I print the value just after I exited the function, the value change and become something like "0#"
Here is the part concerned in the main :
int main()
{
FILE* dico =NULL;
char *motSecret, *motRes;
char lettre=' ';
int check=0, nbCoups=10, longueur=0, nbMots=0;
Bool erreur = TRUE;
srand(time(NULL));
nbMots = scanDico(dico);
getWord(dico, nbMots, motSecret);
printf("Mot : %s", motSecret);
The problem appears after the function getWord(). Here is the code of this function :
void getWord(FILE* dico, int nbLignes, char *mot)
{
int numMotChoisi=rand() % nbLignes, nbChar=0;
char charActuel=' ';
dico = fopen("dico.txt", "r");
rewind(dico);
if(dico != NULL)
{
while (numMotChoisi > 0)
{
charActuel = fgetc(dico);
if (charActuel == '\n')
numMotChoisi--;
}
charActuel = ' ';
while(charActuel != '\n')
{
charActuel = fgetc(dico);
nbChar++;
}
fseek(dico,-(nbChar)-1,SEEK_CUR);
mot = malloc(nbChar * sizeof(char));
if(mot == NULL)
{
printf("Probleme d'allocation memoire");
exit(0);
}
fgets(mot, SIZE, dico);
mot[strlen(mot) - 1] = '\0';
printf("Mot = %s ", mot);
}
fclose(dico);
}
The printf at the end of the function return a good value, and the printf just after the getWord() in the main show that the value changed in the function haven't been "saved"...
Other thing, that works fine without memory allocation.
I hope I'm clear enough. If I forgot to tell something or if you need more informations, please tell me.
C uses pass by value in function parameter passing.
You need a double pointer, something like void getWord(FILE* dico, int nbLignes, char **mot) if you want to allocate memory inside another function.
As a cascased effect, printf("Mot : %s", motSecret); is trying to access uninitialized memory, causing undefined behaviour.
Suggestions:
I see no reason to use FILE *dico as a parameter in getWord(). In can very well be a local.
instead of using double pointer, i would like to recommend returning the allocated pointer from getWord(), i.e., change void getWord() to char * getWord(), add return mot and use like motSecret = getWord(<params>)
char *motSecret;
motSecret is a local variable withing main() and it is not initilized.
By calling
getWord(dico, nbMots, motSecret);
You are passing some uninitialized pointer to a function getword().
Inside getword() you are assigning some memory to
char *mot;
and writing some data to this memory.
Now this memory is not known to motSecret You have to return this memory address to the uninitialized pointer in main()
char *motSecret = getWord(dico, nbMots);
Your getword() should be like,
char *getWord(dico, nbMots);
and inside this after performing everything do,
return mot;

When to free pointers

I'm a bit of a C newbie, so I'm still trying to get my head fully around when to worry about memory issues.
Suppose I have the following simple program:
#include <stdlib.h>
/* this returns a malloc()'d string */
char *get_str(int whichone);
int main(void)
{
char *s;
if ((s = get_str(0)) == NULL) {
exit(1);
}
/* position 1 */
if ((s = get_str(1)) == NULL) { /* position 2 */
exit(2);
}
return 0;
}
Obviously, this simple of a program has no worries about memory. It allocates a few bytes (for all intents and purposes), and it exits provided our dear function didn't fail.
Now, suppose I am running similar code inside of a looping and fork()ing program. Should I be using free(s) at position 1 since at position 2 I leave the old value behind and assign a new location for the pointer?
Yes. free releases the memory associated with the pointer that is being free'd. Once you reassign s so that it holds a different memory location, you will have lost your opportunity to free the memory associated with the original value of s.
You should definetly free the memory at position 1, because once you reassigned s you lost any chance to do so. And I'd do it one way or another because you can never know when somebody else is instructed to build a fork into your application and he will assume you did everything right.
If you have a pointer to memory that have been allocated using one of the malloc() type calls then when you are done with the memory area, you should deallocate the memory using free(). Similarly using calloc(), which also allocates from the heap, should be followed by the use free() to deallocate the memory when done with it.
The other memory allocator such as alloca() which allocates from the stack and not the heap see On the use and abuse of alloca does not use the free() function and that memory will be recovered automatically as the stack pointers are adjusted when the function in which it is used returns. Naturally that means that using a pointer from alloca() is only good for the function and any functions it calls and the address becomes invalid as soon as the function using alloca() returns.
In your simple example, I would use free() just before the call to the get_str(1) function at position 2 so the source would look something like"
int main(void)
{
char *s;
if ((s = get_str(0)) == NULL) {
exit(1);
}
// doing stuff with the string pointed to by s
/* position 1 */
// free up the string area so that we can get another one.
free (s);
if ((s = get_str(1)) == NULL) { /* position 2 */
exit(2);
}
return 0;
}
I might also be tempted to modify your example a touch and do something like the following. This was all written without testing in a compiler so there may be a compilation error or two however this should provide the basic idea.
The idea with this approach is to have a struct that contains state information as well as a pointer so that you will know which type of get_str() pointer came from, if you are interested, and when you call the get_str() function, it will deallocate the memory for you. You could also add intelligence so that if there is memory already allocated and it is the correct type, then you do not do a free() followed by a malloc() but instead just return back.
Another bonus provided by this approach is when a free() is done, the char * member of the struct is set to NULL which should give you a crash if you try to dereference the pointer and since the whichone member of the struct indicates the last type of get_str() used, your debugging may be easier depending on how good you are with interpreting a crash dump.
#include <stdlib.h>
typedef struct {
int whichone;
char *s;
} GetStrStruct;
/* this returns a malloc()'d string */
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct)
{
free(pStruct->s); // we depend on pStruct->s being valid or NULL here
pStruct->s = NULL;
pStruct->whichone = -1;
switch (whichOne) {
case 0: // allocate string one
pStruct->s = malloc (32); // string one type of memory allocation
pStruct->whichone = whichone;
break;
case 1: // allocate string two
pStruct->s = malloc (64); // string two type of memory allocation
pStruct->whichone = whichone;
break;
default:
break;
}
// if the malloc() failed then return a NULL pointer
// we just reuse the pStruct pointer here, it is local and one less variable to make
if (pStruct->s == NULL) pStruct = NULL;
return pStruct;
}
int main(void)
{
GetStrStruct myStruct = {0}; // create and initialize the struct
if (get_str(0, &myStruct) == NULL) {
exit(1);
}
// do things with myStruct.s, the string from last get_str() call
// this would be using myStruct.s and not just myStruct or s so maybe awkward?
/* position 1 */
if (get_str(1, &myStruct) == NULL) { /* position 2 */
exit(2);
}
// do things with the second type of get_str()
// this would be using myStruct.s and not just myStruct or s so maybe awkward?
// release the memory as I am done. This may seem a bit strange to get a nothing string.
get_str (-1, &myStruct);
return 0;
}
If you added a debug facility you could even track which line of source did the last allocation and the last deallocation. Or if the malloc() fails, you could implement a debugger interrupt or other mechanism to immediately stop so you will know exactly which line the function call failed.
In the include file with the prototype for the get_str() function and the GetStrStruct struct you would use C Preprocessor as follows. If you change the 0 in the #if 0 to a 1 then the debug version is enabled otherwise it is not. The idea is to use a macro through the C Preprocessor to replace calls to get_str() with a call to get_str_Debug() and provide additional arguments with the source file path and the line number in the source file.
#if 0
typedef struct {
int whichone;
char *s;
struct {
int lineNo;
char file[64];
} myDebug;
} GetStrStruct;
GetStrStruct *get_str_Debug(int whichone, GetStrStruct *pStruct, char *file, int line);
#define get_str(wo,ps) get_str_Debug (wo,ps,__FILE__,__LINE__)
#else
typedef struct {
int whichone;
char *s;
} GetStrStruct;
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct);
#endif
And then in the implementation file you could use the C Preprocessor with something like the following to allow you to specify whether the get_str() function should be replaced by a get_str_Debug() function with additional debug aids at compile time.
#if defined(get_str)
// provide a prototype for the replacement function signature.
GetStrStruct *get_str_Special(int whichone, GetStrStruct *pStruct);
// provide the debug information wrapper so that we can track where the last use came from
GetStrStruct *get_str_Debug(int whichone, GetStrStruct *pStruct, char *file, int line)
{
GetStrStruct *pTemp = get_str_Special (whichone, pStruct);
if (pTemp) {
// update the debug information. we keep only last 60 chars of file path.
int iLen = strlen (file);
if (iLen > 60) iLen -= 60; else ilen = 0;
strcpy (pStruct->myDebug.file, file + iLen);
pStruct->myDebug.lineNo = line;
} else {
// cause a debugger interrupt or a crash dump or something.
}
return pTemp;
}
GetStrStruct *get_str_Special (int whichone, GetStrStruct *pStruct)
#else
/* this returns a malloc()'d string */
GetStrStruct *get_str(int whichone, GetStrStruct *pStruct)
#endif
{
free(pStruct->s);
pStruct->s = NULL;
pStruct->whichone = -1;
switch (whichOne) {
case 0: // allocate string one
pStruct->s = malloc (32); // string one type of memory allocation
pStruct->whichone = whichone;
break;
case 1: // allocate string two
pStruct->s = malloc (64); // string two type of memory allocation
pStruct->whichone = whichone;
break;
default:
break;
}
// if the malloc() failed then return a NULL pointer
if (pStruct->s == NULL) pStruct = NULL;
return pStruct;
}
Then where ever you use get_str() if you turn on the debugging, the C Preprocessor will substitute a call to get_str_Debug() with the arguments used in the get_str() call along with two additional arguments, a char pointer to the source file name where the get_str() is being replaced by the get_str_Debug() and the source file line number.

2D arrays passed through functions in c

I'm having a problem with my program. I need my program to read from a text file, the first consists of the dimensions of the 2d array the rest is the contents of the array. I have coded the readWord function which reads from textfiles and it works but when i do anything on the main function with the array it crashes. Please could you help.
int main()
{
int num_it, cols, rows;
char** myworld;
num_it = readWorld(myworld,&cols, &rows);
myworld[1][2]='x';/*it crashes when i make this statement*/
}
int readWorld(char** world, int* width,int* height)
{
int result=0,i,cols=0,rows=0;
char buff[25];
FILE* file = fopen ("world.txt", "r");
fscanf(file, "%d %d %d\n", width, height, &result);
/*Dynamic allocation*/
world = (char**)malloc(*(height)* sizeof(char*));
for(i=0;i<*height;i++)
{
world[i] = (char*)malloc(*width*sizeof(char));
}
/*store data in array*/
while(fgets(buff, sizeof buff, file) != NULL)
{
if (strlen(buff) >1){
for(cols=0; cols<=(strlen(buff)); ++cols)
{
world[rows][cols] = buff[cols];
}
++rows;
}
}
fclose(file);
return result;
}
You need to allocate the memory for myworld in the actual caller!
What's happening here is that you are passing the pointer by value to the function.
The pointer value is changed by the function but that's not going to adjust the one in the caller.
Two options: use a triple indirection (ie pass a pointer to the the pointer) or allocate in the main sub. I prefer the latter, mainly because you can control the memory deallocation in a more symmetrical manner; even if you fixed this problem your code still has the memory leak.
What you're experiencing is undefined behaviour as you are attempting to access memory your program does not own.
Your myworld variable in main is never initialized and points to junk, so when you try to access it bad things happen. Think about why: you are passing a copy of the variable to readWorld. You correctly allocate memory inside there, and make the copy point to it, but the original pointer (in main) still points to whatever random location it pointed to before.
If you want the memory for it to be allocated inside the readWorld function and made accessible via the myworld variable in main then you must pass a pointer to myworld to readWorld; in other words, you must pass a triple pointer.
Try this:
int readWorld(char*** world, int* width,int* height)
{
char **tempworld = malloc(...);
// do whatever
*world = tempworld;
return result;
}
int main()
{
char **myworld = NULL;
readWorld(&myworld, ...);
return 0;
}

Is it OK to malloc an array in a called function but free it in the calling function?

I'm not an expert in C, but here's what I'm trying to do:
int main(void) {
double *myArray;
...
myFunction(myArray);
...
/* save myArray contents to file */
...
free(myArray);
...
return 0;
}
int myFunction(double *myArray) {
int len=0;
...
/* compute len */
...
myArray = malloc( sizeof(double) * len );
if (myArray == NULL)
exit(1);
...
/* populate myArray */
...
return 0;
}
I'd like to save the contents of myArray inside main, but I don't know the size required until the program is inside myFunction.
Since I'm using CentOS 6.2 Linux, which I could only find a gcc build available up to 4.4.6 (which doesn't support C99 feature of declaring a variable-length array; see "broken" under "Variable-length arrays in http://gcc.gnu.org/gcc-4.4/c99status.html), I'm stuck using -std=c89 to compile.
Simple answer is no.
You are not passing back the pointer.
use
int main(void) {
double *myArray;
...
myFunction(&myArray);
...
/* save myArray contents to file */
...
free(myArray);
...
return 0;
}
int myFunction(double **myArray) {
int len=0;
...
/* compute len */
...
*myArray = malloc( sizeof(double) * len );
if (NULL == *myArray)
exit(1);
...
EDIT
poputateThis = *myArray;
/* populate poputateThis */
END OF EDIT
...
return 0;
EDIT
Should simplify thigs for your
}
What you are doing is not OK since myFunction doesn't change the value myArray holds in main; it merely changes its own copy.
Other than that, it's OK even if stylistically debatable.
As a question of good design and practice (apart from syntax issues pointed out in other answers) this is okay as long as it is consistent with your code base's best practices and transparent. Your function should be documented so that the caller knows it has to free and furthermore knows not to allocate its own memory. Furthermore consider making an abstract data type such as:
// myarray.h
struct myarray_t;
int myarray_init(myarray_t* array); //int for return code
int myarray_cleanup(myarray_t* array); // will clean up
myarray_t will hold a dynamic pointer that will be encapsulated from the calling function, although in the init and cleanup functions it will respectively allocate and deallocate.
What you want to do is fine, but your code doesn't do it -- main never gets to see the allocated memory. The parameter myArray of myFunction is initialized with the value passed in the function call, but modifying it thereafter doesn't modify the otherwise-unrelated variable of the same name in main.
It appears in your code snippet that myFunction always returns 0. If so then the most obvious way to fix your code is to return myArray instead (and take no parameter). Then the call in main would look like myArray = myFunction();.
If myFunction in fact already uses its return value then you can pass in a pointer to double*, and write the address to the referand of that pointer. This is what Ed Heal's answer does. The double ** parameter is often called an "out-param", since it's a pointer to a location that the function uses to store its output. In this case, the output is the address of the buffer.
An alternative would be to do something like this:
size_t myFunction(double *myArray, size_t buf_len) {
int len=0;
...
/* compute len */
...
if (buf_len < len) {
return len;
}
/* populate myArray */
...
return len;
}
Then the callers have the freedom to allocate memory any way they like. Typical calling code might look like this:
size_t len = myFunction(NULL, 0);
// warning -- watch the case where len == 0, if that is possible
double *myArray = malloc(len * sizeof(*myArray));
if (!myArray) exit(1);
myFunction(myArray, len);
...
free(myArray);
What you've gained is that the caller can allocate the memory from anywhere that's convenient. What you've lost is that the caller has to write more code.
For an example of how to use that freedom, a caller could write:
#define SMALLSIZE 10;
void one_of_several_jobs() {
// doesn't usually require much space, occasionally does
double smallbuf[SMALLSIZE];
double *buf = 0;
size_t len = myFunction(smallbuf, SMALLSIZE);
if (len > SMALLSIZE) {
double *buf = malloc(len * sizeof(*buf));
if (!buf) {
puts("this job is too big, skipping it and moving to the next one");
return;
}
} else {
buf = smallbuf;
}
// use buf and len for something
...
if (buf != smallbuf) free(buf);
}
It's usually an unnecessary optimization to avoid a malloc in the common case where only a small buffer is needed -- this is only one example of why the caller might want a say in how the memory is allocated. A more pressing reason might be that your function is compiled into a different dll from the caller's function, perhaps using a different compiler, and the two don't use compatible implementations of malloc/free.

Resources