Exetools

Exetools (https://forum.exetools.com/index.php)
-   General Discussion (https://forum.exetools.com/forumdisplay.php?f=2)
-   -   How to use malloc in C? (https://forum.exetools.com/showthread.php?t=10088)

Zest 08-24-2006 13:48

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;

}


aProgrammer 08-24-2006 18:20

change
printf("%s",&*(pi + i));
to
printf("%c",*(pi + i));

ArC 08-24-2006 22:37

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.

tom324 08-24-2006 22:54

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;
}


JuneMouse 08-27-2006 01:00

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

Zest 08-27-2006 19:03

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.

JuneMouse 08-28-2006 16:24

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

Zest 09-07-2006 13:31

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.

Harding 09-15-2006 05:44

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/

mantovano 02-17-2010 03:19

The book "The C programming Lenguage" (Kernighan & Ritchie) is a good startup

JMI 02-17-2010 10:49

Were you paying any attention that you were responding to a 4 year old post??? ;)

Regards,


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

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2026, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX