Contribute  :  Web Resources  :  Past Polls  :  Site Statistics  :  Downloads  :  Forum  
    BiW ReversingThe challenge is yours    
 Welcome to BiW Reversing
 Tuesday, November 29 2022 @ 11:57 AM CET
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to use malloc in C?

 
Post new topic   Reply to topic    www.reversing.be Forum Index -> Coding Corner
View previous topic :: View next topic  
Author Message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Wed Aug 23, 2006 1:57 pm    Post subject: How to use malloc in C? Reply with quote

Hi,
I'm 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 amnd 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 Exclamation Question

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;

}

Back to top
View user's profile Send private message
SKiLLa
Frequent poster
Frequent poster


Joined: 29 Mar 2005
Posts: 79

PostPosted: Wed Aug 23, 2006 2:59 pm    Post subject: Reply with quote

Well, since you're using:
Code:
      r = scanf("%s",&pi[i]);

You could use:
Code:
      printf("%s", &pi[i]);


I'm not sure wether that's your intented output (don't think so), but it makes your code work Wink
If you just want some 'string-array' you should make it either a fixed length or use a $0 terminator-/seperator-char ...
Back to top
View user's profile Send private message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Thu Aug 24, 2006 6:32 am    Post subject: Reply with quote

Dear SKiLLa,
Hello,
Thanks for your reply.
But
Code:
 &*(pi + i)
and
Code:
&pi[i]
is the same in result.
The first is pointer notation and the latter is the array notation, which have the same result and function when compiled.
The fact is that the code still doesn't work.

What do you mean by fixed lenght array?
May I ask you to explain more?

Also by sayiong "$0 terminator" do you mean to use this function after scanf()?

putchar('\0');

Is it what I have to do?

Thanks in advance.
Regards,
Zest.
Back to top
View user's profile Send private message
Knight
Regular
Regular


Joined: 21 Aug 2005
Posts: 122

PostPosted: Thu Aug 24, 2006 6:43 am    Post subject: Reply with quote

Before getting down to business i must say that you have forgotten to release used memory.
Anyways... With malloc you have allocated chars array, not strings array (single string could be seen as chars array (if you use oop it most likely will have some functions on operating on it too)).
If you want to store several strings in one buffer you should, as SkiLLa suggested, store them separated by '\0'. Then there's no nice solution. Code could look like this:
Code:
int nLen = 0;
pi = (char *) malloc(50 * sizeof(char));
for(int i = 0; i < 5; i++)
{
   if(!scanf("%s", pi + nLen))
      break;   //actually this way to solve bad input problem is bit bad
   nLen += strlen(pi + nLen) + 1;   //one for terminating '\0'
}
nLen = 0;
for(int i = 0; (i < 5) && pi[nLen]; i++)   //secondary conditions is needed
                  //because of possible 'break'
                  //in previous loop
{
   printf("%s\n", pi + nLen);
   nLen += strlen(pi + nLen) + 1;
}
free(pi);

I haven't tried to compile and run it, but i'm pretty sure it works Wink
Well you could do it also in the way that everything would look more like string array:
Code:
char *pi[5];   //5 pointers to chars
for(int i = 0; i < 5; i++)
{
   pi[i] = (char*)malloc(50 * sizeof(char));
   scanf("%s", pi[i]);   //we could have second loop for this,
            //but this results in smaller & faster code
}
for(int i = 0; i < 5; i++)
{
   printf("%s\n", pi[i]);
   free(pi[i]);      //same as above
}


Hope it helps.

Regards,
Knight

P.S. If you're coding in plain C (not C++), then you might need some changes to code (like declaring i in begining of function).
Back to top
View user's profile Send private message
stingduk
Regular
Regular


Joined: 19 Feb 2005
Posts: 148

PostPosted: Thu Aug 24, 2006 8:53 pm    Post subject: Reply with quote

i didnt understand really

the code you posted compiles and works

it takes strings

and also prints them out

here is a sample output

start
a
b
free
gabba
flunky
abfgflunky
bfgflunky
fgflunky
gflunky
flunky
Done!

it works exactly like it is programmed to work
it took all the five input
and printed out all the five output
waited for getch
and terminated

you are incrementing i by 1 so it naturally will erase the remaining chars and would add the next input in its place

so if you see a,b,(f 0f free) (g of gabba) full string (flunky)

you want it print it full increment i by the size of input in scanf
Back to top
View user's profile Send private message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Sun Aug 27, 2006 12:04 pm    Post subject: Reply with quote

Hi,
Thank you so much everybody who has tried to help me 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 code I can see that you didn't follow the rule.
You have somethinmg like this in the code:

scanf("%s", pi + nLen);

and also

printf("%s\n", pi + nLen);

or these statements in the second part

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

and

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

Could you please explain the rule that you have used in the program?



And at last I should admit that Knight is a skillful programmer and his code
works properly.

Best Regards,
Zest.
Back to top
View user's profile Send private message
Knight
Regular
Regular


Joined: 21 Aug 2005
Posts: 122

PostPosted: Mon Aug 28, 2006 7:23 am    Post subject: Reply with quote

With 'exp' example you're right. Also following can be changed a little:
Code:
scanf("%d",&exp[1]); -> scanf("%d", exp + 1 * sizeof(int));

Because exp is pointer (address) itself you only need to calculate needed offset. Though this is not very nice way... This answers your question about pi + nLen. We just calculate right address to start, pi is base of buffer and nLen is offset of current string.
Second code example uses array of pointers. So:
pi -> address of 5 pointers char.
pi[some_index] -> pointer to (address of) char array.
It's kinda like in first example, just we have 5 buffers, each of which can be accessed using [] operator. Because in this case every buffer contains only single string we don't need to calculate offsets anymore, all strings start at the begining of array.

Regards,
Knight
Back to top
View user's profile Send private message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Sat Sep 02, 2006 2:02 pm    Post subject: Reply with quote

Dear Knight,
Hi,
Thanks for the explanation.
Now everything is clear.

I just have one mnore question which is not related to this case.
Take a lok at this function prototype.

char *strncpy(char *dest, const char *src, size_t maxlen);

I has used an element which is named "size_t"
I used below statement to get the length of size_t and I got the result of 4 bytes,which is infact the same length an integer has in C programming.

printf("%d", sizeof(size_t));

I want to know what size_t is and how we should use it.
Also why we don't use INT instead of it.

By the way,suggest a good book on C whihc is worth buying and reading.

Have a nice day.
Best Regards,
Zest.
Back to top
View user's profile Send private message
Knight
Regular
Regular


Joined: 21 Aug 2005
Posts: 122

PostPosted: Sat Sep 16, 2006 9:39 am    Post subject: Reply with quote

Sorry for late reply, i've been offline all those two weeks.

size_t is really defined as unsigned int. Why it is so? I don't really know and I'm not going to guess, but such things are used a lot in programming, take WIN32 API as example: HWND, HMODULE, HINSTANCE, HBITMAP, HICON, LPSTR, LPCSTR... They are all redefined basic C types. Good thing is that in C/C++ u can use typecasts (when u're know what u're doing) so all this bunch of types doesn't causes bigger trouble. So u can use unsigned int instead of size_t (well signed too, but if value is negative results are unpredictable, in general that would be bad coding style).
Book... hard case, believe it or not but i haven't read any (well i read, but only some parts, not whole). Couple good tuts that i've read myself are http://www.cplusplus.com/doc/tutorial/ and http://winprog.org/tutorial/ (this one about WIN32 API in C). But these covers only basics, if u need deeper knowledge you either need some book (which i cannot recomend any) or practice (probably much longer way, but imo much more fun Smile).

Regards,
Knight
Back to top
View user's profile Send private message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Fri Sep 22, 2006 5:17 am    Post subject: Reply with quote

Dear Knight,
Hi,
Thank you so much for your explanation and help.
I got everything I wanted to know.
Also the tuts you mentiond seem to be very nice.

Best Regards,
Zest.
Back to top
View user's profile Send private message
Zest
Frequent poster
Frequent poster


Joined: 24 Apr 2005
Posts: 56

PostPosted: Fri Oct 06, 2006 10:17 pm    Post subject: Reply with quote

Dear Knight,
Hi,
I faced an alternative answer to my previous question.
I found it in a book about C programing.

I thought that you might be interested to know this fact.

Here is this answer:
Quote:

we've mentioned the size_t type, which represents the type returned by the sizeof operator, and the time_t type, which represents the type of value returned by the time() function. The C standard says sizeof and time() return integer types but leaves it up to the implementation to determine which type. The reason for this lack of specificity is that the ANSI C committee feels that no one choice is likely to be the best choice for every computer platform. So they make up a new type name, such as time_t, and let the implementation use a typedef to set that name to some specific type. That way, they can provide a general prototype such as the following:


time_t time(time_t *);


On one system, time_t can be unsigned int; on another, it can be unsigned long. As long as you include the time.h header file, your program can access the appropriate definition, and you can declare time_t variables in your code.



Regards,
Zest.
Back to top
View user's profile Send private message
Knight
Regular
Regular


Joined: 21 Aug 2005
Posts: 122

PostPosted: Thu Oct 12, 2006 10:38 pm    Post subject: Reply with quote

This clears things up.
Thanx for info.

Regards,
Knight
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    www.reversing.be Forum Index -> Coding Corner All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group
 Copyright © 2022 BiW Reversing
 All trademarks and copyrights on this page are owned by their respective owners.
Powered By Geeklog 
Created this page in 0.91 seconds