This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c dynamic memory allocation and sizeof()
I am trying to find the cache block by keeping a huge block of 16 MiB and by trying to access different elements each time to find the time. I just can't write the length of the array.
How can I write a for loop to iterate over the array. I need the length of the array; how can I find that? I have tried sizeof(a)/sizeof(a[0]) but this doesn't work or I am doing something wrong because my assignment sheet tells me it can hold 4 million int's..
register *a;
a = malloc(16777216);
int i;
for (i = 0; i < sizeof(a)/sizeof(a[0]); i = i + 1) {
printf("\ni = %d", i);
}
This only prints i = 0 i = 1.
The code sizeof(a) simply returns the size of the pointer register *a, and is completely unrelated to the size of the array that a points to.
C arrays do not track how many items they contain. You can use this syntax only if the size of the array is known at compile time. But you can't do it with an array allocated this way.
For this task, you'll need to track this information yourself. You can store that value in a variable, or you could append an array element with a special value that indicates it's the end of the array (much like we do with C strings).
a is a register pointer an not an array. so sizeof(a) will not return 16MB as you are expecting. please use 16777216 directly instead of sizeof()
Related
This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 2 years ago.
#include <stdio.h>
#include <conio.h>
int main() {
int arr[] = {1,2,3};
arr[3] = 4;
printf("%d", sizeof(arr) / sizeof(1)); // To print the length of arr
getch();
return 0;
}
I first created this array of length 3 and then at index 3 I put 4 as its value. So the length should be 4 now, but still, after compiling it is printing 3. Why?
Arrays in C do not automatically extend themselves if you index outside the defined range. When you write
arr[3] = 4;
you are writing outside the bounds of the array.
The problem is that C does not require any kinds of bounds checking on array accesses and places no requirement on the compiler or runtime environment to handle out-of-bounds indexing in any particular way - the behavior is undefined. Any result is possible, including appearing to work as expected. You could also overwrite another variable. You could corrupt the stack frame leading to a crash later.
An array's size is fixed over its lifetime. You can allocate space dynamically with malloc or calloc and resize it using the realloc function, but again that doesn't happen automatically, you have to write the code to keep track of the current size and resize as necessary.
Why is the length of the array 3 ...
Because you defined it like that here
int arr[] = {1,2,3};
Using [] and three initialisers, size 3, not going to change.
... when I have added 4 elements?
You did not add 4 elements, you created it with initially three elements, they were not added.
You did not even add a single element later.
In this code
arr[3] = 4;
you wrote a value to a memory location just behind the array. The array is not changed by that, especially not its size. Doing this causes Undefined Behaviour by the way.
C is like that, it allows you to do all kind of unwise things, without kindly telling you.
You cannot create an array and then try to resize it. Arrays have a fixed size. If you want to store data dynamically, that is, with variable size, you need to use data structure.
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 5 years ago.
I'm having issues with my program, and I'm trying to break it down and I'm seeing that I'm having issues with memory allocation at a minimum.
I have a struct:
typedef struct{
int originX;
int originY;
char ticBoard[3][3];
int result;
int turn;
} simBoard;
I would expect the size of this struct (one single instance of it) to be (4 ints * 4 bytes) + (1 bye char * 3 * 3) or 25 bytes. When I run the sizeof() function on simBoard, I get a value of 28 bytes. I'm assuming that it's the 25 + 3 extra that I don't need to worry about.
The main issue is when I try to declare an array of this struct
simBoard* boardArray = (simBoard*)malloc(sizeof(simBoard)*size));
Assume size is some constant for this scenario. To my knowledge this should create an array of the simBoard struct, of size size. I should be able to go
boardArray[3]
And get the 4th item of boardArray correct? However I'm running into an issue with the memory allocation. When I run:
printf("%zu is the size of the array\n", sizeof(boardArray));
The return value is 8. I even tried to further sort out the issue:
simBoard* boardArray = (simBoard*)malloc(224);
When I ran the printf again, I'm still getting a value of 8 bytes for boardArray. If you guys could lead me in the right direction that'd be fantastic, as I'm absolutely stumped here.
Thank you!
You can indeed index the 4th struct in the array using the notation boardArray[3].
Bear in mind though that boardArray itself is a pointer type. That explains your printf output. Arrays with dynamic storage duration and pointer types are inextricably linked in C. For the avoidance of doubt, sizeof(boardArray) is sizeof(simBoard*).
C doesn't provide functionality to obtain the length of an dynamic array. You need to remember the length yourself.
Don't forget to call free(boardArray) when your done. The C runtime library will take appropriate measures to ensure that all the struct elements are freed.
This question already has answers here:
C sizeof a passed array [duplicate]
(7 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 7 years ago.
I wrote the following function in C:
void dummy(int* my_array, int size)
{
//my implementation
}
Is there any way to check whether size is REALLY the size of my_array?
For example, if I call the function and use for my_array an array with 4 elements but pass 5 for size, is there any way to know that 5 is not really the size of the array?
Thank you in evidence.
You're looking at it the wrong way. An array is contiguous piece of memory. In C, you can represent this concept with a pointer to its start and its size. Since your array is represented by a <my_array, size> tuple, it doesn't make sense to talk about my_array's size, since it's only the start-pointer of the array.
unfortunately, there is no such way in C. As an array is always a pointer to an arbitrary address in memory, there is no such thing as "array bounds" that can be checked.
This is why many of the C functions have that special size parameter: because there's no other way of determining an array's size.
The size of the array is however big you made it when you declared and initialized it.
int my_array[100] = {0}; has a size of 100.
int my_other_array[50] = {0}; has a size of 50.
If you want the length of the data, then you're thinking in more abstract terms than the language can handle. The length of your data is a non-measurable parameter when the language does not support it.
If my_array is dynamically allocated (with malloc) you can get the size of memory block but it depends on specific compiler. Unfortunately in most cases there is address alignments and you will not have the exact size to 1 byte but aligned to 32 bits or other.
Is there a way we can copy every element from one multidimensional array to another multidimensional array by just doing one memcpy operation?
int array1[4][4][4][4];
int array2[4][4][4][4];
int main()
{
memset(&array1,1,sizeof(array1));
memset(&array2,0,sizeof(array2));
printf_all("value in array2 %d \n",array2[1][1][1][1]);
memcpy(&array2,&array1,sizeof(array2));
printf("memcopied in array2 from array1 \n");
printf("value in array2 %d \n",array2[1][1][1][1]); //not printing 1
}
Your code is correct. You should not expect the output to show you a value of 1. You should expect it to show you a value of 16843009, assuming a 4 byte int.
The reason is: you are filling array1 with bytes of value 1, not with ints of value 1. i.e. binary 00000001000000010000000100000001 (0x01010101) is being filled into all the int elements with your memset operation.
So regardless of the size of int on your machine (unless it's a single byte!) you should not expect to see the value 1.
I hope this helps.
Yes, your code should already be correct.
You have to consider memory layout when doing this. The arrays are all in one block, multi dimensional is essentially a math trick done by the compiler.
Your code says copy this memory content to the other memory block. since both share the same layout they will contain the same values.
The following code also just copies the values, but access is handled differently so you would have to think about how to get the order of elements correct.
int array1[4][4][4][4]; //elements 256
int array2[256];
int main()
{
memcpy(&array2,&array1,sizeof(array1)); //will also copy
// original access via: a + 4 * b + 16 * c + 64 * d
}
Multidimensional array in C is a flat block of memory with no internal structure. Memory layout of a multidimensional array is exactly the same as that of a 1-dimensional array of the same total size. The multidimensional interface is implemented through simple index recalculation. You can always memcpy the whole multidimensional array exactly as you do it in your code.
This, of course, only applies to built-in multidimensional arrays, explicitly declared as such (as in your code sample). If you implement a hand-made multidimensional array as an array of pointers to sub-arrays, that data structure will not be copyable in one shot with memcpy.
However, apparently you have some misconceptions about how memset works. Your memset(&array1,1,sizeof(array1)); will not fill the array with 1s, meaning that your code is not supposed to print 1 regardless of which array you print. memset interprets target memory as an array of chars, not as an array of ints.
memset can be used to set memory to zero. As for non-zero values, memset is generally unsuitable for initializing arrays of any type other than char.
I am trying to print a dynamic array, but I am having trouble with the bounds for the array.
For a simple example, lets say I'm trying to loop through an array of ints. How can I get the size of the array? I was trying to divide the size of the array by the size of the type like this sizeof(list)/sizeof(int) but that was not working correctly. I understand that I was trying to divide the size of the pointer by the type.
int *list
// Populate list
int i;
for(i = 0; i < ????; i++)
printf("%d", list[i]);
With dynamic arrays you need to maintain a pointer to the beginning address of the array and a value that holds the number of elements in that array. There may be other ways, but this is the easiest way I can think of.
sizeof(list) will also return 4 because the compiler is calculating the size of an integer pointer, not the size of your array, and this will always be four bytes (depending on your compiler).
YOU should know the size of the array, as you are who allocated it.
sizeof is an operator, which means it does its job at compile time. It will give you the size of an object, but not the length of an array.
So, sizeof(int*) is 32/62-bit depending on architecture.
Take a look at std::vector.
There is no standardized method to get the size of allocated memory block. You should keep size of list in unsigned listSize like this:
int *list;
unsigned listSize;
list = malloc(x * sizeof(int));
listSize = x;
If you are coding in C++, then it is better to use STL container like std::vector<>
As you wrote, you really did tried to divide the size of a pointer since list is declared as a pointer, and not an array. In those cases, you should keep the size of the list during the build of it, or finish the list with a special cell, say NULL, or anything else that will not be used in the array.
Seeing some of the inapropriate links to C++ tools for a C question, here is an answer for modern C.
Your ideas of what went wrong are quite correct, as you did it you only have a pointer, no size information about the allocation.
Modern C has variable length arrays (VLA) that you can either use directly or via malloc. Direcly:
int list[n];
and then your idea with the sizeof works out of the box, even if you changed your n in the mean time. This use is to be taken with a bit of care, since this is allocated on the stack. You shouldn't reserve too much, here. For a use with malloc:
int (list*)[n] = malloc(*list);
Then you'd have to adapt your code a bit basically putting a (*list) everywhere you had just list.
If by size you mean the number of elements then you could keep it in a counter that gets a ++ each time you push an element or if you dont mind the lost cycles you could make a function that gets a copy of the pointer to the first location, runs thru the list keeping a counter until it finds a k.next==null. or you could keep a list that as a next and a prev that way you wouldnt care if you lost the beginning.