Malloc and scanf

I am competent enough in several scripting languages, but I finally force myself to learn raw C. I just play with some basic things (I / O right now). How can I allocate heap memory, save a line in allocated memory and push it back? This is what I have right now, how can I make it work correctly?

#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char *toParseStr = (char*)malloc(10); scanf("Enter a string",&toParseStr); printf("%s",toParseStr); return 0; } 

I'm currently getting weird output like '8' \ 'for example.

+4
source share
5 answers
  char *toParseStr = (char*)malloc(10); printf("Enter string here: "); scanf("%s",toParseStr); printf("%s",toParseStr); free(toParseStr); 

First, the line in scanf indicates the input it is about to receive. To display a string before accepting keyboard input, use printf as shown.

Secondly, you do not need to dereference toParseStr since it points to a character array of size 10, like you toParseStr using malloc . If you used a function that would point to another place in memory, then &toParseStr is required.

For example, suppose you want to write a function to allocate memory. Then you will need &toParseStr since you are changing the contents of the pointer variable (this is the address in memory - you can see for yourself by typing its contents).

 void AllocateString(char ** ptr_string, const int n) { *ptr_string = (char*)malloc(sizeof(char) * n); } 

As you can see, it takes a char ** ptr_string which reads as a pointer that stores a memory cell of a pointer that will store the memory address (after the malloc operation) of the first byte of the allocated block of n bytes (right now). it has some memory address for garbage, as it is not initialized).

 int main(int argc, char *argv[]) { char *toParseStr; const int n = 10; printf("Garbage: %p\n",toParseStr); AllocateString(&toParseStr,n); printf("Address of the first element of a contiguous array of %d bytes: %p\n",n,toParseStr); printf("Enter string here: "); scanf("%s",toParseStr); printf("%s\n",toParseStr); free(toParseStr); return 0; } 

Thirdly, it is recommended to free the allocated memory. Despite the fact that this is your entire program, and this memory will be freed upon exiting the program, it is still good practice.

+8
source

You need to specify scanf the conversion format so that it knows that you want to read the line - right now you are just showing what kind of garbage occurred in the memory you allocated. Instead of trying to describe all the problems, here is some code that should be at least close to working:

 char *toParseStr = malloc(10); printf("Enter a string: "); scanf("%9s", toParseStr); printf("\n%s\n", toParsestr); /* Edit, added: */ free(toParseStr); return 0; 

Edit: In this case, the free string has no real meaning, but as others have pointed out, it is a good habit to improve nonetheless.

+9
source

Using scanf() (or fscanf() for data you don't control) with the standard specifier "% s" is an almost certain way to get into a buffer overflow problem.

A classic example is that it enters the line “This line is longer than 10 characters” into your program, after which there will be chaos, cats and dogs will start to sleep together, and a naked singularity may well appear and swallow the Earth (most people simply state “undefined behavior” "but I think my description is better).

I actively discourage the use of features that cannot provide protection. I urge you (especially as a C newbie) to use fgets() to read your input, since you can control buffer overflows with it much easier, and it is more suitable for simple line input than scanf() .

After you have a line, you can call sscanf() on it with your heart-shaped contents, which, by the way, you do not need to do in this particular case, since you still get a raw line.

I would use:

 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFSZ 10 int main(int argc, char *argv[]) { char *toParseStr = malloc(BUFFSZ+2); if (toParseStr == NULL) { printf ("Could not allocate memory!\n"); return 1; } printf ("Enter a string: "); if (fgets (toParseStr, BUFFSZ+2, stdin) == NULL) { printf ("\nGot end of file!\n"); return 1; } printf("Your string was: %s",toParseStr); if (toParseStr[strlen (toParseStr) - 1] != '\n') { printf ("\nIn addition, your string was too long!\n"); } free (toParseStr); return 0; } 
+4
source

You don't need & before toParseStr in scanf , since it is already a pointer

also call free(toParseStr) after

+3
source

Firstly, the errors that caused your program to work: scanf(3) accepts a format string, like printf(3) , and not a printable string for the user. Secondly, you passed the address of the toParseStr pointer, not the toParseStr pointer.

I also removed the unnecessary translation from your call to malloc(3) .

Improving your program still consists in using the scanf(3) a option to allocate memory for you - so some joker inserting ten characters in your line will not start stomping in unallocated memory. (Yes, C will allow someone to rewrite almost the entire address space with this program, as it is written. A giant security flaw. :)

 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char *toParseStr = malloc(10); printf("Enter a short string: "); scanf("%s",toParseStr); printf("%s\n",toParseStr); return 0; } 
0
source

Source: https://habr.com/ru/post/1316376/


All Articles