![]() |
|
|
|
#1
|
|||
|
|||
|
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;
}
|
|
#2
|
|||
|
|||
|
change
printf("%s",&*(pi + i)); to printf("%c",*(pi + i)); |
|
#3
|
|||
|
|||
|
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;
}
Code:
for( i=0; i<5; i++ )
{
printf( "%s", &pi[i*10] );
}
|
|
#4
|
|||
|
|||
|
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;
}
|
|
#5
|
|||
|
|||
|
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;
}
Code:
start rrrrrrrrrrrrrrrrrrrrr ttttttttttttttttttttttt yyyyyy zest malloc rrrrrrrrrrrrrrrrrrrrr ttttttttttttttttttttttt yyyyyy zest malloc Done! have fun |
|
#6
|
|||
|
|||
|
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. |
|
#7
|
|||
|
|||
|
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] 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 |
|
#8
|
|||
|
|||
|
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. |
|
#9
|
|||
|
|||
|
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/ |
|
#11
|
|||
|
|||
|
Were you paying any attention that you were responding to a 4 year old post???
![]() Regards,
__________________
JMI |
![]() |
| Thread Tools | |
| Display Modes | |
|
|