Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 08-24-2006, 13:48
Zest
 
Posts: n/a
How to use malloc in C?

Hi,
I am a newbie in programming in C language.
I wanted to use malloc function to make a data storage and use it to store some strings and then show them up.
So I coded what you see below but it doesn't work properly.
I doesn't accept strings and also when it tries to show the results all the data is displayed disorderly.

Even using " a , b , c , d , e " as the input data won't result in showing " a , b , c , d , e " as output data.

I hope someone can shed some light and let meknow how to correct the code.
Also as far as I know we don't need to use "&" operator with printf(); function,but I had to use it or my code would result in crash.
I don't know why this behaviour is emerged.
That's strange for me :!:

Thanks in advance.
Best Regards,
Zest.


Code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int main(void)
{
   char * pi;
  int i,r;
   puts("start");
   pi = (char *) malloc(50 * sizeof(char));
   
   
  for(i = 0; i < 5; i++)
  {
  r = scanf("%s",&pi[i]);
    if(r != 1)
    break;
   

 
}
      i = 0;
      while(i < 5)
      {
        printf("%s",&*(pi + i));
        putchar('\n');
           i++;
          }
   
          free(pi);
          puts("Done!");
         
     


  getch();
  return 0;

}
Reply With Quote
  #2  
Old 08-24-2006, 18:20
aProgrammer
 
Posts: n/a
change
printf("%s",&*(pi + i));
to
printf("%c",*(pi + i));
Reply With Quote
  #3  
Old 08-24-2006, 22:37
ArC ArC is offline
VIP
 
Join Date: Jan 2003
Location: NTOSKRNL.EXE
Posts: 172
Rept. Given: 0
Rept. Rcvd 1 Time in 1 Post
Thanks Given: 5
Thanks Rcvd at 17 Times in 12 Posts
ArC Reputation: 1
The malloc is correct but the way you assign values to pi is not.
I assume you want to store zero terminated strings in the buffer allocated by malloc.
You have to define a maximum length for all strings you enter (e.g. 10 bytes/characters). In the for loop you then write:
Code:
for(i = 0; i < 5; i++)
{
  r = scanf("%s",&pi[i*10]);
    if(r != 1)
      break;
}
Now when you want to print all strings you would write
Code:
for( i=0; i<5; i++ )
{
  printf( "%s", &pi[i*10] );
}
This should print out everything correctly as long as the strings you enter are not longer than 9 characters.
Reply With Quote
  #4  
Old 08-24-2006, 22:54
tom324 tom324 is offline
Friend
 
Join Date: Jan 2002
Posts: 233
Rept. Given: 5
Rept. Rcvd 7 Times in 6 Posts
Thanks Given: 26
Thanks Rcvd at 28 Times in 17 Posts
tom324 Reputation: 7
Check his code. And consider using multidimensional arrays .

Tom

Code:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char  *pi;
   int   i, r, j, len;
   puts("start");
   char tmp_str[50];
   pi = (char*)malloc(50 * sizeof(char));


   if ( pi == NULL )
   {
      /* error handler here */
   }

   memset(pi, 0, 50 * sizeof(char));

   for ( i = 0, len = 0; i < 5; i++ )
   {
      printf("Enter element %d = ", i);
      r = scanf("%s", tmp_str);
      if ( r != 1 )
      {
         break;
      }
      else
      {
         sprintf(&pi[len], "%s ", tmp_str);
         len += strlen(tmp_str) + 1;
      }
   }
   /*-----------------24.08.2006 16:35-----------------
    * pi is one dimensional array holding 5 elements separated by spaces
    *  "a b c d e"
    * --------------------------------------------------*/

   printf("array '%s'\n", pi);

   i = 0;
   len = 0;
   while ( i < 5 )
   {
      j = sscanf(&pi[len], "%s[^ ]", tmp_str);
      if ( j == 1)
      {
         printf("%s", tmp_str);
         len += strlen(tmp_str) + 1;
      }
      putchar('\n');
      i++;
   }

   free(pi);
   puts("Done!");

   return 0;
}
Reply With Quote
  #5  
Old 08-27-2006, 01:00
JuneMouse
 
Posts: n/a
well basically the design is not good but you can make it work like that if you just
assign the increment values correctly no need to have fixed string length
you can do variable string length as long as you take care not to overflow your malloc size

Code:
#include <stdio.h> 
#include <conio.h> 
#include <stdlib.h> 

int main(void) 
{ 
   char * pi; 
  int i,r,len[5]= {0},wen =0 ,foo=0; 
   puts("start"); 
   pi = (char *) malloc(50 * sizeof(char)); 
    
    
  for(i = 0; i < 5; i++) 
  { 
  r = scanf("%s%n",&pi[wen],&len[i]); //len[i] will hold the length of input
    if(r != 1) 
    break;
	if(i==0)
    	wen = wen + len[i]+ 1; //first time we need to add a 0 terminator
        else
	wen = wen + len[i];    // from second time no need coz it will point right
  
} 
      i = 0; 
      while(i < 5) 
      { 
        printf("%s",&*(pi + foo )); 
        putchar('\n'); 
	if(i==0)
             foo = foo + len[i] + 1; //same as above skip 0 terminator
	else
	foo = foo + len[i];    // no need second time onwards
	i++;
          } 
    
          free(pi); 
          puts("Done!"); 
          
      


  getch(); 
  return 0; 

}
output

Code:
start
rrrrrrrrrrrrrrrrrrrrr
ttttttttttttttttttttttt
yyyyyy
zest
malloc
rrrrrrrrrrrrrrrrrrrrr
ttttttttttttttttttttttt
yyyyyy
zest
malloc
Done!
but ill advise you get a c book or c++ book and leaf through them

have fun
Reply With Quote
  #6  
Old 08-27-2006, 19:03
Zest
 
Posts: n/a
Hi,
Thank you so much everybody who has tried to help me in this topic.
I learned some new points in programming by looking at your skillfully
coded programs in this topic.

Sorry but,I still have some problems and I hope you can shed some lingt
to clarify the obscure points.

I know that,as a convention, the name of an array is the same as the address
of its first element.
So when you want to use an array in scanf() function you don't need to use
ampersand operator(&) with its name and you just type the name of the array.
But for the second or other elements of that array you need to use (&) to be able
to point at the address of that element.
But this rule is not devised for printf() function.
In printf() function you can easily type the name that element and the printf() function shows
what is inside that element.

For example if you have an array witch is named exp your prohgram should work considering following
statements:

int exp[20]= {0};

exp == &exp[0];

so

scanf("%d",exp); // it should work properly

but for the second element you should code this statemant:

scanf("%d",&exp[1]);

but for printf you can just use this statement:

printf("%d",exp[0]); //without ampersand operator

I hope up to now I'm correct about this rule.

But in your code I can see that you have used ampersand operator with
both of the functions scanf() and printf().

For example ARC has used these statements:

***
scanf("%s",&pi[i*10]);

printf("%s\n",&pi[i*10]);
***

Again JuneMouse has used these ones:

***
scanf("%s%n",&pi[wen],&len[i]);

printf("%s",&*(pi + foo ));
***

Maybe I'm cionfused because we are using pointers in the program and you
can use ampersand in this way while you have pointers.

Could you please explain the fact?
Also let me know if we can use pointer without the ampersand operator
in out code.

The second obscure point for me is to know how this part of program works:


wen = wen + len[i]+ 1; //first time we need to add a 0 terminator
else
wen = wen + len[i]; // from second time no need coz it will point right

I want to know why we shouldn't increment "wen + len[i]" in the second time.
what will happen here that we don't need to add it to one?


If you don't mind please explain.
Thanks in advance.
Best Regards,
Zest.
Reply With Quote
  #7  
Old 08-28-2006, 16:24
JuneMouse
 
Posts: n/a
best way is to think about it and draw out the sequnce either in your head or using some tools that you can gather

for example you could have opened excel layed out the entire memory
in a column and taken your input and filled each of memory values manually
and assigned them an address which would have cleared your doubts

try making flow charts, graphs layout diagrams or if you dont have the patience to do all this
open a debugger and step through your own code in assembly several times
and it will show you exactly what are you accessing with you i, foo ,wen,len etc


Code:
0	pi [0]	a					aaaaaaaa
1	pi [1]	a					bbbbb
2	pi [2]	a					ccccc
3	pi [3]	a					rr
4	pi [4]	a					eee
5	pi [5]	a					
6	pi [6]	a					
7	pi [7]	a					
8	pi [8]		len[0]=9 so wen = 10				
9	pi [9]						
10	pi [10]	b					
11	pi [11]	b					
12	pi [12]	b					
13	pi [13]	b					
14	pi [14]	b	len[1] = 6	so wen = 10+6  == 16			
15	pi [15]						
16	pi [16]	c					
17	pi [17]	c					
18	pi [18]	c					
19	pi [19]	c					
20	pi [20]	c	len[2] = 6	so wen = 16+6 ==22			
21	pi [21]						
22	pi [22]	r					
23	pi [23]	r	len[3] =3 so wen = 22 +3 ==25				
24	pi [24]						
25	pi [25]	e					
26	pi [26]	e					
27	pi [27]	e	len[4] = 4 wen = 25+4 ==29				
28	pi [28]						
29	pi [29]						
30	pi [30]						
31	pi [31]						
32	pi [32]						
33	pi [33]						
34	pi [34]						
35	pi [35]						
36	pi [36]						
37	pi [37]						
38	pi [38]						
39	pi [39]						
40	pi [40]						
41	pi [41]						
42	pi [42]						
43	pi [43]						
44	pi [44]						
45	pi [45]						
46	pi [46]						
47	pi [47]						
48	pi [48]						
49	pi [49]						
50	pi [50]
basically no one over here was or will be willing to nitpick your program

every one has thier own stereotypes (they read i cant use malloc and they glance at your code ) and they normally will code thier own variations

they would never care if you used (&*(pi) or &pi
and the answers will not reflect on these points

you are supposed to learn these finer points of & and * and (*) and &* and *& and *(&) and &(*) by reading through books and or practicing
coding and answering the true or false questions in those books

if you really note those true or false questions in the books will obviously have all the above variations

anyway i just cleared up the doubt about your not taking string and i provided a referance solution

its neither foolproof nor submissible as evidence in some doctoral thesis

i borked out at the first working sequnce of code that took least modification from your original code i havent checked up *& &* etc

and may be you dont need to add the null terminator even the first time
and directly do wen = wen + len[i]

i did not check i added that block of if else just to be sure
not because its etched in steel rule

glance through the code and grasp the bigger picture
you wont find answers to finer points in any ones code
unless you ask a specific question (like how do you use * and &) and then you will be directed to some c c++ newbie forum or may be some one will post a refernace to k&r or bjarnes book still you wont get a right exact answer

get a book practice (repeat thier examples in hard copy ) make typos change
the examples find what errs find why it errs
and after a few days of time you wont be asking these question but will be
doing the right thing without you even observing you did it right
Reply With Quote
  #8  
Old 09-07-2006, 13:31
Zest
 
Posts: n/a
Dear JuneMouse,
Hi,
Your explanation was clear and it made everything manifest.
Just as the last question I want to know which book is the best for learning C programming in details.
Searchng in amazon I found a lot of books about C programming but I couldn't decide which one to buy.
Please recommend me a book which is worth buying and reading.
Thanks in advance.
Regards,
Zest.
Reply With Quote
  #9  
Old 09-15-2006, 05:44
Harding
 
Posts: n/a
What you need is a couple of hours at Google to find some nice sites with info. A c-reference is nice to have to when coding.

An example is hxxp://wxw.cprogramming.com/reference/
Reply With Quote
  #10  
Old 02-17-2010, 03:19
mantovano
 
Posts: n/a
The book "The C programming Lenguage" (Kernighan & Ritchie) is a good startup
Reply With Quote
The Following User Gave Reputation+1 to For This Useful Post:
upb (02-19-2010)
  #11  
Old 02-17-2010, 10:49
JMI JMI is offline
Leader
 
Join Date: Jan 2002
Posts: 1,627
Rept. Given: 5
Rept. Rcvd 199 Times in 99 Posts
Thanks Given: 0
Thanks Rcvd at 98 Times in 96 Posts
JMI Reputation: 100-199 JMI Reputation: 100-199
Were you paying any attention that you were responding to a 4 year old post???

Regards,
__________________
JMI
Reply With Quote
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



All times are GMT +8. The time now is 00:20.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )