LinuxQuestions.org
Did you know LQ has a Linux Hardware Compatibility List?
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 12-24-2006, 12:06 PM   #1
cpd05
Member
 
Registered: Jan 2006
Distribution: Debian
Posts: 90

Rep: Reputation: 15
dynamic memory allocation - malloc, scanf!


Hello,

I'm learning C at the moment and am confused about how to dynamically allocate memory at runtime.
If I wanted to read a variable sized string from stdin, how could I do that? I assume I can use scanf but what do I use as the variable for scanf. How can I allocate the memory for the scanf variable before I know how long the string is, but how can find out the size of the string before I've read it in.
Does that make sense? Am I getting things totally wrong?

Thanks

chris.
 
Old 12-24-2006, 12:32 PM   #2
kaz2100
Senior Member
 
Registered: Apr 2005
Location: Penguin land, with apple, no gates
Distribution: Debian testing woody(32) sarge etch lenny squeeze(+64) wheezy jessie
Posts: 1,430

Rep: Reputation: 83
Hi,

Your penguin can do whatever you CAN tell (describe) to do. If there is no way for you to know what you want to do, you do not know what you want to do.

So,
Quote:
Does that make sense?
makes sense. So that, you already know the answer.

One way of doing your job is, 1) decide whatever size, 2) read that many data from stdin, 3) do what you want 4) repeat 2-3 while you have input.

Happy Penguins!
 
Old 12-24-2006, 01:47 PM   #3
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
You are asking two separate questions. How to limit the amount of data input, to avoid buffer overflows and other BAD THINGS. And, how to allocate memory for said buffers at runtime. The answer is that you can allocate memory with the malloc/calloc/alloca family of functions (and then free() the memory when done). The amount of memory allocated can then be used as an argument in a call to 'fread()'. The data thus acquired can be parsed using sscanf(), or strtok(), or any number of other ways, depending upon your requirements.

Hope this helps.

--- rod.
 
Old 12-24-2006, 07:48 PM   #4
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi, cpd05 -

Like the previous posters said, you simply have to guess the biggest string you're likely to encounter ... and then make sure you can deal with it if the actual string turns out to be bigger.

It doesn't matter if you use "malloc()" or simply declare an array (I chose to use an array in the example below).

Unfortunately, there is usually no way to determine the size a priori, then allocate enough space on-the-fly.

Here's an example:
Code:
#include <stdio.h>

#define MAX_BUF 8

int
main(int argc, char *argv[])
{
  char buf[MAX_BUF];
  char *s;

  s = fgets (buf, sizeof (buf), stdin);
  printf ("buf= %s, strlen (buf)= %d, s= %s...\n",
    buf, strlen (buf), s);
  return 0;
}
Quote:
./x
123456789
buf= 1234567, strlen (buf)= 7, s= 1234567...
<= YOU'LL NOTICE THAT "FGETS" AUTOMATICALLY TRUNCATES THE
STRING TO THE LENGTH YOU SPECIFIED (INCLUDING ONE BYTE FOR
THE '\0' STRING TERMINATOR)
'Hope that helps .. PSM
 
Old 12-25-2006, 01:45 AM   #5
introuble
Member
 
Registered: Apr 2004
Distribution: Debian -unstable
Posts: 700

Rep: Reputation: 31
A bit on paulsm4's solution above. Notice that he uses a call to fgets. This function makes sure the buffer isn't overflown, unlinke it's sister/cousin/whatever function gets(). Always make sure you use the former and not the latter.

Also note that in the above example, paulsm4 uses buf and s; which have the same value and thus seem (are?) unneeded. He did this to show you what the return value of fgets() is. You should check out `man fgets` (check out the portion of gets() too; also make sure to read the "return value" section).

I suppose what you want to do is allocate exactly as much memory as you need in order to store the string. There is no real way of doing this, as you have no control on the user's input. Here's something you could do:

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

#define MAX_INPUT_SIZE 1024

int main(int argc, char **argv)
{
	char *p, *q;

	if ((p = malloc(MAX_INPUT_SIZE)) == NULL) {
		perror("malloc");
		return EXIT_FAILURE;
	}

	if (fgets(p, MAX_INPUT_SIZE, stdin) == NULL) {
		perror("fgets");
		return EXIT_FAILURE;
	}

	if ((q = malloc(strlen(p) + 1)) == NULL) {
		perror("malloc");
		return EXIT_FAILURE;
	}

	strcpy(q, p);
	free(p);
	printf("%s", q);
	return EXIT_SUCCESS;
}
 
Old 12-25-2006, 04:37 PM   #6
Dan04
Member
 
Registered: Jun 2006
Location: Texas
Distribution: Ubuntu
Posts: 207

Rep: Reputation: 37
Code:
#include <stdio.h>
#include <stdlib.h>

#define INITIAL_BUFFER_SIZE 16

char *readline(FILE *input) {
   char *buffer;
   int byteRead;
   int count = 0;
   int capacity = INITIAL_BUFFER_SIZE;

   if ((buffer = malloc(capacity)) == NULL) {
      perror("malloc");
      return NULL;
   }

   while ((byteRead = fgetc(input)) != '\n') {
      buffer[count++] = byteRead;

      if (count >= capacity) {
         capacity *= 2;

         if ((buffer = realloc(buffer, capacity)) == NULL) {
            free(buffer);
            perror("realloc");
            return NULL;
         }
      }
   }

   buffer[count] = '\0';
   return buffer;
}

int main() {
   char *str;

   printf("Enter a string: ");
   str = readline(stdin);
   printf("You typed: %s\n", str);
   free(str);
   return 0;
}
 
Old 12-28-2006, 06:11 PM   #7
cpd05
Member
 
Registered: Jan 2006
Distribution: Debian
Posts: 90

Original Poster
Rep: Reputation: 15
cheers people, I think I get it now
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Dynamic Memory Allocation jvff Programming 1 09-05-2005 05:01 AM
dynamic memory allocation failure guam Programming 4 04-13-2005 09:16 AM
dynamic memory allocation in kernel module appas Programming 4 09-21-2004 06:36 AM
pointers and dynamic memory allocation deveraux83 Programming 2 01-24-2004 10:35 AM
Dynamic Memory Allocation query dhanakom Programming 2 07-21-2003 02:19 PM


All times are GMT -5. The time now is 10:29 AM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration