Reputation: 4655
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.
Upvotes: 0
Views: 198
Reputation: 2113
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.
Upvotes: 1
Reputation: 76918
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.
Upvotes: 2
Reputation: 55593
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;
...
}
Upvotes: 1
Reputation: 98118
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;
Upvotes: 1