LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-02-2011, 06:29 AM   #1
golden_boy615
Member
 
Registered: Dec 2008
Distribution: Ubuntu Fedora
Posts: 445

Rep: Reputation: 18
how to memory allocate in function and call it by reference for array structure


hello
I am writing a function(in C language in Linux) to initialize an array of a structure from a mysql table by calling a function by reference but I have a problem with call this function by reference . this is my program:

PHP Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <mysql/mysql.h>
#include <mysql/errmsg.h>

struct ATable {
    
int    id;
    
char   sid[60];
};

void Init_Table(MYSQL *conn,struct ATableATable)
{
    
MYSQL_ROW row;
    
MYSQL_RES *result;
    
int num_rows;
    
char q="Select id,sid From table";
    
unsigned int Curent_Row=0;
    if(
mysql_query(conn,q)==0)
    {
        
result=mysql_store_result(conn);
        if(
result!=NULL)
        {
            
num_rows mysql_num_rows(result);     
[
B][I]            ATable=(struct ATable*)malloc(num_rows*sizeof(struct ATable));[/I][/B]
            while((
row=mysql_fetch_row(result))!=NULL)
            {
                
ATable[Curent_Row].id=atoi(row[0]);
                
sprintf(ATable[Curent_Row].sid,"%s",row[10] ? row[10] : "NULL");
                
Curent_Row++;
            }
        }
        
mysql_free_result(result);
    }
    else if(
mysql_field_count(conn)>0)
    {
        
fprintf(stderr,"No result set,mysql_store_result() faild : %s\n",mysql_error(conn));
    }
    else
    {
        
printf("Query was not meant to return data.\n");
    }
}

int main()
{
    
MYSQL *conn;
    
struct ATable *ATable;
    
unsigned int Curent_Row=;
    
conn mysql_init(NULL);
    if (!
mysql_real_connect(conn"127.0.0.1","root","1","database",0,"/var/run/mysqld/mysqld.sock",0)) 
    {
        
fprintf(stderr"%s\n"mysql_error(conn));
        return(
0);
    }
    
Init_Table(conn,ATable);
    while (
Curent_Row<127)
    {
        
printf("id=%d sid=%s  \n\n",ATable[Curent_Row].id,ATable[Curent_Row].sid);
        
Curent_Row++;
    }
    return 
0;

I understood that the problem is with my "malloc" inside function but I don't know how to solve it I mean I understood that when function allocate a memory for local ATable variable and when it comes out of function it frees that memory so I get segmentation fault in accessing that array.
what can I do for such a problem ?
how can I malloc inside a function and use it outside a function with calling that function with reference or something like this?

Last edited by golden_boy615; 07-02-2011 at 06:32 AM.
 
Old 07-02-2011, 06:52 AM   #2
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Tagging your C code as CODE might make this thread more readable than (what you did) tagging it as PHP.

Quote:
Originally Posted by golden_boy615 View Post
hello
I am writing a function(in C language in Linux) to initialize an array of a structure from a mysql table by calling a function by reference but I have a problem with call this function by reference .
What do you think you mean by "call ... by reference"?

In C++, you can pass parameters by reference. In C you can't.

If your code were passing ATable by reference, it would still have a memory leak, but it would successfully get the data transferred out of the function (which seems to be your main issue).

Since C has no pass by reference, you can get the same semantic effect (with an uglier syntax) by adding an extra layer of indirection.

You have:
Quote:
Code:
void Init_Table(MYSQL *conn,struct ATable* ATable)
...
        ATable=(struct ATable*)malloc(num_rows*sizeof(struct ATable));
...
        ATable[Curent_Row].id=atoi(row[0]);
        sprintf(ATable[Curent_Row].sid,"%s",row[10] ? row[10] : "NULL");
...
...
    Init_Table(conn,ATable);
An extra layer of indirection would be:

Code:
void Init_Table(MYSQL *conn,struct ATable** ATable)
...
        *ATable=(struct ATable*)malloc(num_rows*sizeof(struct ATable));
...
        (*ATable)[Curent_Row].id=atoi(row[0]);
        sprintf((*ATable)[Curent_Row].sid,"%s",row[10] ? row[10] : "NULL");
...
...
    Init_Table(conn,&ATable);
I added an extra * to every use of ATable in Init_Table and added & to the point where the outside ATable is passed into the function. That has the same effect as pass by reference would.

Quote:
when it comes out of function it frees that memory
False. With or without my change, your code never frees that memory. That is a memory leak.

Without my change, your code loses the pointer to the memory on exit from the function. ATable inside the function is not the same variable as ATable outside the function. So your code had only ATable inside the function pointing to the allocated memory. ATable outside the function never pointed to anything, so it seg faulted on use.

My change gets ATable outside the function to point to the allocated memory. You should also make a change to free that memory when you are done with it.

Last edited by johnsfine; 07-02-2011 at 07:04 AM.
 
1 members found this post helpful.
Old 07-02-2011, 04:12 PM   #3
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Rep: Reputation: 22
Deffining something outside a function is like static (inside) so global deffined but runtime specific to a name space.

Incidental: Keep in mind if that name space gets not tuched at runtime (created on the heap - new, malloc) that global deffinition don't exist (runtime error could occure)!!!

To access a static deffined class (struct) inside a name space you have to recast that class - redeffine the access. Such access deffinitions are normal be done in haeder files so you simple can include them and the compiler does know how something is accessed and handeled. (That is what I think you mean with reference)

A struct is the same like a class and can have a init, a exit and member functions - oh sorry this is C++ specific I guess. So a class instead should be the tidiest way.

atable.h :
Code:
#ifndef ATABLE_H
#define ATABLE_H   // name space ATABLE_H

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <errno.h> 
#include <mysql/mysql.h> 
#include <mysql/errmsg.h>

class ATable
	{
	public:

	ATable(MYSQL *conn);   //init function

	~ATable();   //exit function
	
	struct record_t   // definition of type record_t
		{
		int    id; 
		char   sid[60];
		} *table_1;   // define a pointer of record_t for allocation: table_1 = new record_t[200];
	
	int add_record( record_t* );
	int del_record( record_t* );
	...
	// all methods/members you need
	};

#endif   // ATABLE_H
atable.c according ...
 
Old 07-03-2011, 03:21 AM   #4
alireza976
LQ Newbie
 
Registered: May 2011
Posts: 13

Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
Tagging your C code as CODE might make this thread more readable than (what you did) tagging it as PHP.

Code:
void Init_Table(MYSQL *conn,struct ATable** ATable)
...
        *ATable=(struct ATable*)malloc(num_rows*sizeof(struct ATable));
...
        (*ATable)[Curent_Row].id=atoi(row[0]);
        sprintf((*ATable)[Curent_Row].sid,"%s",row[10] ? row[10] : "NULL");
...
...
    Init_Table(conn,&ATable);

Hello

how can free the memory from this code?
 
Old 07-03-2011, 02:20 PM   #5
bastl
Member
 
Registered: Sep 2003
Location: Germany/BW
Distribution: My own
Posts: 237

Rep: Reputation: 22
Quote:
Originally Posted by alireza976 View Post
Hello
how can free the memory from this code?
maybe you mean:
Code:
free(  ATable );
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash array Add function example using indirect array reference as function argument bobywelsh Programming 10 07-05-2010 04:44 AM
[bash] indirect array reference to array with values containing spaces Meson Linux - Software 9 06-04-2010 09:38 PM
Tough problem: Cannot allocate memory for a simple cp call! svar Linux - General 3 01-07-2006 08:24 AM
Tough problem: Cannot allocate memory for a simple cp call! svar Linux - General 4 01-06-2006 10:48 AM
How to allocate memory for a multidimensional array ? indian Programming 12 11-19-2004 03:37 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:52 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration