Need help with malloc in C programming. It allocates more space than expected

Let me preface this by saying that I am a beginner and im in the entry-level class C at school.

I am writing a program that requires me to use malloc and malloc, allocating the 8x space that I expect in all cases. Even when only for malloc (1), this is a distribution of 8 bytes instead of 1, and I'm confused about the reason.

Here is my code that I tested. This should only allow one character input plus an escape character. Instead, I can enter 8, so it allocates 8 bytes instead of 1 , this is true even if I just use an integer in malloc() . Please ignore the variable x , it is used in a real program, but not in this test.

 #include <stdio.h> #include <string.h> #include <stdlib.h> int main (int argc ,char* argv[]){ int x = 0; char *A = NULL; A=(char*)malloc(sizeof(char)+1); scanf("%s",A); printf("%s", A); free(A); return 0; } 
+4
source share
9 answers
  A=(char*)malloc(sizeof(char)+1); 

going to allocate at least 2 bytes (sizeof (char) is always 1). I don’t understand how you determine that it allocates 8 bytes, however malloc allows you to allocate more memory than you ask, but not less.

The fact that you can use scanf to write a longer line to the memory pointed to by A does not mean that you have allocated memory. It will overwrite everything that is, which may lead to a crash of your program or unexpected results.

+6
source

malloc allocates as much memory as you requested.

If you can read more than the allocated bytes (using scanf ), because scanf also reads from your own memory: this is a buffer overflow.

You must limit the scanf data that can be read as follows:

 scanf( "%10s", ... ); // scanf will read a string no longer than 10 
+5
source

I am writing a program that required me to use malloc and malloc to allocate 8x space, which I expect cases from it. Even when just for malloc (1), this is a distribution of 8 bytes instead of 1, and I'm confused why.

Theoretically speaking, how you do something in a program does not highlight 8 bytes .

You can still enter 8 bytes (or any number of bytes), since there is no verification in C that you are still using a valid recording location.

What you see is Undefined Behaviour , and the reason is that you write in memory that you do not need. There was nothing in your code that stops the program after the bytes n you selected were used.

You can get Seg Fault now or later or never. This is Undefined Behavior. Just because it works does not mean that it is right.

Now your program can really allocate 8 bytes instead of 1.

The reason for this is Alignment

The same program may allocate a different size on another computer and / or in another operating system.

Also, since you are using C , you really don't need to quit. To get started, check out this one .

+3
source

Your code has no restrictions on how much data you can load with scanf , which will lead to a buffer overflow (security / crash error). You should use a format string that limits the amount of data read in one or two bytes that you allocate. The malloc function is likely to allocate extra space to round the size, but you should not rely on this.

+2
source

What system do you work on? If it is a 64 bit bit, it is possible that the system allocates the smallest possible block that it can. 64 bits - 8 bytes.

EDIT: Note only:

 char *s = malloc (1); 

Calls 16 bytes for iOS 4.2 (Xcode 3.2.5).

+1
source

malloc allows you to allocate more memory than you ask. This is only necessary in order to ensure at least as much as you ask, or fail if it cannot.

+1
source

using malloc or creating a buffer on the stack will allocate memory in words.

On a 32-bit system, the word size is 4 bytes, so when you request

A=(char*)malloc(sizeof(char)+1);

(which is essential A=(char*)malloc(2);

the system will actually give you 4 bytes. On a 64-bit machine, you should get 8 bytes.

The way you use scanf is dangerous because it overflows the buffer if the line is larger than the allocated size, leaving the heap overflow vulnerability in your program. scanf in this case will try to fill a string of any length into this memory, therefore, it will not be used to calculate the allocated size.

+1
source

If you enter 8 , if you just allocate 2 bytes sizeof(char) == 1 (unless you are on some obscure platform) , and you write the number with the char number. Then on printf it will print the number that you saved there. Therefore, if you save the number 8, the command line will display 8. It has nothing to do with the number of characters selected. Unless, of course, you looked in the debugger or somewhere else that it really allocates 8 bytes.

0
source

scanf does not know how large the target buffer is. All he knows is the starting address of the buffer. C does not check boundaries, therefore, if you pass it a buffer address, the size of which should contain 2 characters, and you enter a string of 10 characters, scanf will write these additional 8 characters into memory after the end of the buffer.This is called buffer overflow, which is common malicious exploit. For some reason, six bytes immediately after your buffer are not β€œimportant”, so you can enter up to 8 characters without visible obvious effects.

You can limit the number of characters read in a scanf call by including an explicit field width in the conversion specification:

 scanf("%2s", A); 

but you still need to make sure that the target buffer is large enough to accommodate this width. Unfortunately, there is no way to dynamically indicate the width of the field, as it is with printf :

 printf("%*s", fieldWidth, string); 

because %*s means something completely different in scanf (basically, skip the next line).

You can use sprintf to create your own format string:

 sprintf(format, "%%%ds", max_bytes_in_A); scanf(format, A); 

but you have to make sure that the format buffer is wide enough to hold the result, etc. etc. etc.

This is why I usually recommend fgets() for interactive input.

0
source

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


All Articles