Assuming that a memory address occupies 4 bytes and a char occupies 1 byte:
char** t;
t = malloc(5 * sizeof(char*));
int i;
for (i = 0; i < 5; i++)
t[i] = malloc(sizeof(char) * (i+1));
A minimum of around 35 bytes -- but a typical implementation of malloc will have some minimum allocation size it supports, so in reality, you can expect it to use more memory than that (though exactly how much more will vary).
In a typical case, the minimum allocation will be something like 16 or even 32 bytes, in which case most of the sizes you specified above don't really make any difference -- the last 5 allocations will all be of whatever the minimum happens to be. In a typical case, sizes larger than that will be rounded up to the next power of 2 as well.
That would give 32 bytes for your first allocation, and either 16 or 32 (i.e., the minimum supported size) for each of your other five, for a total of either 112 or 192 bytes.
35 bytes (Look below for breakup)
char** t;
t = malloc(5 * sizeof(char*)); // 5 * 4 = 20 bytes
int i;
for (i = 0; i < 5; i++)
t[i] = malloc(sizeof(char) * (i+1)); //1 + 2 + 3 + 4 + 5 = 15 bytes
Let the computer compute for you:
char** t;
t = (char**) malloc(5 * sizeof(char*));
int i;
for (i = 0; i < 5; i++)
t[i] = (char*) malloc(sizeof(char) * (i+1));
unsigned int sz = 5 * sizeof(char*);
for (i = 0; i < 5; i++)
sz += sizeof(char) * (i+1);
printf("%d\n", sz);
35 on a 32 bits machine.
20 for that
t = malloc(5 * sizeof(char*));
15 for that: 5+4+3+2+1
int i;
for (i = 0; i < 5; i++)
t[i] = malloc(sizeof(char) * (i+1));
Get how many bytes are allocated ON YOUR SYSTEM with, for example
#define malloc(s) mm(s)
void *mm(size_t s) {
printf("allocating %d ...\n", (int)s);
return (malloc)(s);
}
/* your code */
Of course, you can sum the sizes instead of printing them.
The malloc() allocates space rounded up to 16 bytes (at least in win32), so you'll use 32 bytes in the first alloc and 16*5 in the loop.
There is also overhead of malloc (both, time and memory), because malloc() puts a special header, _CrtMemBlockHeader before the memory area it returns (that's why you have to give exactly the same pointer to the free() and are able to use functions like _msize().
So, the memory amount actually used would be 32 + 80 = 112 bytes.
Considering also the overhead for header: + 5 * sizeof(__CrtMemBlockHeader)
the final amount can be as high as 300 bytes, that is ~8 times larger than the expected 35.
Related
Hello I keep getting invalid next size when using realloc to allocate more memory to an array which im trying to add 100,000 numbers too. I dont know why because im not understanding why it wont work. My code is here below.
int main()
{
printf("starting");
int i;
int *bubbleSortArray = (int *)malloc(sizeof(int));
int numberOfElements = 0;
int randomNumber;
srand(time(NULL));
int j;
for (int j = 0; j <= 100000; j = j +1)
{
randomNumber = rand();
if(numberOfElements != 0)
{
bubbleSortArray = (int *) realloc(bubbleSortArray, numberOfElements * sizeof(int));
}
bubbleSortArray[numberOfElements] = randomNumber;
numberOfElements = numberOfElements + 1;
}
}
In the statement you need to write at least like
bubbleSortArray = (int *) realloc(bubbleSortArray, ( numberOfElements + 1 )* sizeof(int));
Otherwise this statement
bubbleSortArray[numberOfElements] = randomNumber;
invokes undefined behavior.
Also you need to use an intermediate pointer to store the return value of the call of realloc because the function can return a null pointer. In this case the previous value stored in the pointer bubbleSortArray will be lost and you will not have an access to the already allocated memory.
So it would be better to write
int *tmp = (int *) realloc(bubbleSortArray, ( numberOfElements + 1 )* sizeof(int));
if ( tmp != NULL )
{
bubbleSortArray = tmp;
}
else
{
// some other code
}
Pay attention to that these declarations
int i;
int j;
are redundant because the declared variables are not used.
Oh, this is kind of scary. I'm not sure why you're not allocating enough space up front. But this code is going to realloc 100,000 times, which is an insane thing to do. Do you know what realloc does under the hood? I'll explain.
First, it does a NEW alloc of the amount of data. So the first time you loop, numberOfElements is zero, and you use your malloc'd space. But the second time it allocates space for 2 integers, then 3 integers, then 4, et cetera.
So it allocates 8 bytes. It remembers how much it allocated last time (4 bytes -- the size of an int on most systems), and it then does a memcpy of that much space.
Then it memcpy's 8 bytes. then it memcpy's 12 bytes, and so on and so on.
Bad, bad, bad.
What most people do is keep track of two values -- the amount of space allocated (capacity) and the amount used (count or numberOfElements).
So it looks something like this:
int capacity = 16;
int *bubbleSortArray = (int *)malloc(capacity * sizeof(int));
...
if (numberOfElements >= capacity) {
// Increase capacity by whatever means you want.
// You can double it. Or you can:
capacity += 16;
bubbleSortArray = (int *) realloc(bubbleSortArray, capacity * sizeof(int));
}
Ah, and as I cut & pasted your code, I see that you used numberOfElements. So you were consistently undersizing your realloc by 1, anyway.
I've got an unusual condition.
Here's the snippet:
int i, j;
short ** s = (short **)malloc(128);
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
for(j = 0; j < 128; j++)
s[i][j] = 0;
}
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);
s[1][108] = 99;
printf("Value of s[%d][%d] = %d\n",2,40,s[2][40]);
The output I get when I run this is:Value of s[2][40] = 0
Value of s[2][40] = 99
Eliminating the loops and writing short s[14][128] yields the correct output (Value of s[2][40] is 0 in both prints)
Why am I able to access s[2][40] with s[1][108]?
I'm using gcc on Ubuntu 12.04.
You are accessing out of bounds of the space you allocated, which causes undefined behaviour.
s[i] = (short *)malloc(128) allocates 128 bytes. But then you try to write 128 shorts to that space. Since shorts are bigger than 1 byte, you run off the end of the allocation.
Also, short ** s = (short **)malloc(128); probably allocates too much space, since you only use 14 rows.
Assuming you want an array of 14 x 128 the way is:
short **s = malloc( 14 * sizeof *s );
for (size_t i = 0; i < 14; ++i)
s[i] = malloc( 128 * sizeof *s[i] );
malloc takes the number of bytes, so you have to multiply the number of elements by the size of each element.
Note that if you do not need the feature of being able to make different rows different sizes then you can allocate it in a single bloc:
short (*s)[128] = malloc( 14 * sizeof *s );
and in both cases you can use s[i][j] the same.
Finally, you should also check that the pointer returned by malloc is not NULL, and also free the pointer after you are finished with the memory.
First it is not a correct way of allocating memory for 2D array-
short ** s = (short **)malloc(128);
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
This is wrong way!
short ** s = (short **)malloc(128);
Here you are allocating memory for array of 128 bytes for short **.
for(i = 0; i < 14; i++){
s[i] = (short *)malloc(128);
But you are using only 14 short *. That is only 28 bytes used(because sizeof(short) = 2).
Why am I able to access s[2][40] with s[1][108]?- Because you are accessing the array out of bounds!
How?
s[i] = (short *)malloc(128);
This will allocate memory for array of 128 bytes for each short *. That means you can store Maximum 64 short elements in Each 1D array.
But you are trying to access s[1][108] - means 108th element in the 1st row of the array. It is Out of bounds for the allocated memory. So you will not get the expected output.
Try to allocate memory like this-
short **s = malloc(sizeof(short *) * 14);
for(i = 0; i < 14; i++){
s[i] = malloc(sizeof(short) * 128);
I'm trying to allocate a dynamic two dimensional array in C using the following code:
int **allocateMatrix(int rows, int columns) {
int i = 0;
int **p = NULL;
p = (int**) calloc(rows, sizeof(int*));
for(; i < rows; i++) {
p[i] = (int*) calloc(columns, sizeof(int));
}
return p;
}
The code works but actually it's allocating double the memory it needs.
For example, if i pass the arguments rows = 2 and columns = 3 i get an array that's 2 rows by 8 columns.
Am i doing something wrong?
Thank you.
Edit:
The content of the matrix (which is loaded from a file) is:
-1 5 0
4 0 2
And this is what the memory looks like after the allocation and the assignment of the values:
It is allocating the correct amount of memory, but it allocating more memory than a simple 2D array would use because what you've created is not a simple 2D array.
Assuming a 32-bit system (so sizeof(int) == sizeof(int *), and sizeof(int) == 4), then:
a simple 2D array needs 2 x 3 integers = 6 x 4 = 24 bytes
a dynamic 2D array needs 2 pointers plus 2 x 3 integers = 8 x 4 = 32 bytes
That's before there's any accounting for overhead in the memory allocations. So not twice, but more.
The advantages of what you're doing is you can write p[i][j] and get the right result. If you simulated a simple 2D array, you'd have to do the subscript calculation yourself: p[i*3+j] or use (*p)[i][j], depending on exactly how you defined the pointer p.
AFAICT, your screenshot of the array having 20 elements is because.. you told Netbeans (with that #20) to display 20 elements starting at a memory location (**(matrix)). What happens when you change it to be '#3'?
However, based on this comment:
Actually it's more than the double. I know because when i try to assign values they're not contiguous in memory but they are shifted (i can see it from the watches in the debug window in netbeans).
When you allocate memory, you're calling a library that figures out how to request from the operating system what space it may use and then of what space it's been given by the operating system what it hasn't used yet.
You're making assumptions about how the allocator works that may or may not be correct. It's possible for it to allocate space efficiently in a way you don't expect, especially due to virtual paging mechanisms. In short, contiguous calls to the allocator are not guarenteed to allocate contiguous memory, and rarely will.
If you want to use an array-of-pointers for a double array style structure and absolutely must have contiguous addresses in a more "expected" way, you can try this:
int **allocateMatrix(int rows, int columns) {
int i = 0;
int **p = NULL;
int *d = NULL;
p = (int**) calloc(rows, sizeof(int*));
d = (int*) calloc(rows * columns, sizeof(int));
for(; i < rows; i++) {
p[i] = d + i * columns;
}
return p;
}
(code not tested)
that's not because it haves a bidimensional array size (rows*columns*sizeof(int*)) to store the pointers and a bidimensional array space to store the real values (rows*columns*sizeof(int))?
You can use the following approach (no extra memory needed for storing data, actually 1D continuous array in memory):
#include <stdlib.h>
#include <stdio.h>
int (*allocateMatrix(int rows, int columns))[]{
int (*p)[columns] = calloc(rows, columns * sizeof(int)),
i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
p[i][j] = rows*i + j;
}
}
return p;
}
int main(int argc, char *argv[]) {
int rows = 4, cols = 5,
(*array)[cols] = allocateMatrix(rows,cols);
int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("array[%d][%d] = %2d\n", i, j, array[i][j]);
}
}
free(array);
return 0;
}
Output:
array[0][0] = 0
array[0][1] = 1
array[0][2] = 2
array[0][3] = 3
array[0][4] = 4
array[1][0] = 4
array[1][1] = 5
array[1][2] = 6
array[1][3] = 7
array[1][4] = 8
array[2][0] = 8
array[2][1] = 9
array[2][2] = 10
array[2][3] = 11
array[2][4] = 12
array[3][0] = 12
array[3][1] = 13
array[3][2] = 14
array[3][3] = 15
array[3][4] = 16
I should be allocating enough memory for my char**. I used gdb and found the point of the segmentation fault. I've been stuck on this part for about an hour and can't seem to figure out why I'm segfaulting.
Output of program:
size: 10, 20
start: 1, 1
end: 10, 20
Segmentation fault (core dumped)
10 = m1.xsize
20 = m1.ysize
1 = m1.xstart
1 = m1.ystart
10 = m1.xend
20 = m1.yend
snippet of my code:
typedef struct mazeStruct
{
char** arr;
int xsize, ysize;
int xstart, ystart;
int xend, yend;
} maze;
/* read in the size, starting and ending positions in the maze */
fscanf (src, "%d %d", &m1.xsize, &m1.ysize);
fscanf (src, "%d %d", &m1.xstart, &m1.ystart);
fscanf (src, "%d %d", &m1.xend, &m1.yend);
/* print them out to verify the input */
printf ("size: %d, %d\n", m1.xsize, m1.ysize);
printf ("start: %d, %d\n", m1.xstart, m1.ystart);
printf ("end: %d, %d\n\n", m1.xend, m1.yend);
//allocating memory for 2d char array
m1.arr = (char**)malloc(m1.xsize+2 * sizeof(char*));
for(i = 0; i < m1.xsize+2; i++)
m1.arr[i] = (char*)malloc(m1.ysize+2);
/* initialize the maze to empty */
for (i = 0; i < m1.xsize+2; i++) <---- when i = 6 it seg faults
for (j = 0; j < m1.ysize+2; j++)
m1.arr[i][j] = '.';
Am I not allocating enough memory or what am I doing wrong?
Your expression:
m1.xsize + 2 * sizeof(char*)
is equivalent to:
(m1.xsize) + (2 * sizeof(char*))
due to precedence of operators, which is not what you want. You need to instead use:
(m1.xsize + 2) * sizeof(char*)
By way of example, let's say you have m1.xsize set to 20 and your pointer size is four bytes. Hence you need space for 22 pointers, which is 88 bytes. The expression m1.xsize + 2 * sizeof(char*) gives you 20 plus double the size of a pointer, totaling 28 bytes, nowhere near enough for what you want to do.
As an aside, you should also stop casting the return value of malloc() since it can hide certain subtle errors. C is perfectly capable of implicitly casting the void* returned from malloc() into any other pointer type.
int getbit(int * list, int n)
{
return (list[n / 32] >> (n % 32)) & 1;
}
void setbit(int * list, int n)
{
list[n / 32] |= 1 << (n % 32);
}
int main()
{
FILE * out;
int size = 99; //2000000000;
int root = sqrt(size);
int * list = malloc(size / 8.0); //(2*10^9)/8
memset(list, 0, sizeof list);
int i, j;
for (i = 2; i <= root; i++)
for (j = 2 * i; j < size; j += i)
setbit(list, j);
printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
out = fopen("output.txt", "w");
printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
/*for (i=2; i<size; i++)
if (!getbit(list, i))
fprintf(out, "%d\n", i);
fclose(out);*/
return 0;
}
Whenever I use the fopen() in between printf, the value of the third parameter changes from 1 to 0. If I comment out the line then the value is same. What might be the reason behind this?
You see undefined behavior: sizeof(list) is probably 4 or 8 bytes, depending on the architecture, so memset with zeros does not go past the forth byte. You are reading from the third 32-bit word, which came from malloc and has not been initialized by the memset yet. Moreover, you are allocating 12 bytes (size/8.0 gets converted to int; it never makes sense to pass a float or a double to malloc, because you cannot allocate fractional bytes) so accessing the 98-th bit goes past the allocated area.
You should fix these undefined behaviors: allocate enough memory by using
// count needs to be a multiple of sizeof(int)
// The math gets pretty ugly here, but it should work:
int count = sizeof(int)*(size+(8*sizeof(int))-1)/(8*sizeof(int));
int * list = malloc(count);
Then initialize the data to zero by using the proper size:
memset(list, 0, count);
You're writing in memory you do not own, that has an undefined behavior.
Firstly, you're allocating only 12 bytes here:
int* list = malloc(size / 8.0);
You should do this (just giving you the idea, I don't know how many bytes you really want to allocate..):
int* list = malloc((size / 8.0) * sizeof(*list));
Secondly, you are memsetting only 4 bytes (if you're on 32bits system) here:
memset(list, 0, sizeof list);
You should do this:
memset(list, 0, (size / 8.0) * sizeof(*list));
Finally, the only reason your call to fopen() changes things, is because fopen() allocates memory.
Good luck.