getting size of array/vector in c [duplicate] - c

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 3 years ago.
I'm trying to get size of an array in c and for some reason I'm getting a wrong answer for this popular method.
int innerprod(int *v, int *u)
{
int n = sizeof(v)/sizeof(v[0]);
printf("%d\n",n); // ouptut here is giving me '2' for a '3' size array
double result = 0.0;
for (int i = 0; i < n; i++)
{
result += v[i]*u[i];
printf("%d\n",v[i]*u[i]);
}
return result;
}
int main()
{
int V[3] = {3,4,-1}; //a 3 size array
int W[3] = {7,-2,3};
int x = innerprod(&V,&W);
printf("%d\n",x);
}

Unfortunately arrays in C do not have boundary checking and have no way of knowing the length. Arrays are literally pointers into memory where your elements are lined up after another. You use the provided index to compute the memory location of the demanded element. Eg. adress of a[2] = a += 2. Accessing an elements outside the range of your array will most probably (this is also the best case) result in a segmentation fault. If not you will corrupt the memory of something which you should not be able to.
If you want this functionality you could use c++ with vectors from the <vector> library. Or you could build a struct which includes an entry for the size of the array.

Related

Memcpy returns contents of C array as pointers [duplicate]

This question already has answers here:
C / C++ How to copy a multidimensional char array without nested loops?
(7 answers)
Closed 2 years ago.
I wanted to copy the contents of a c array to that of another, and I realized that you cant simply do
array1 = array2;
instead, you should either use a for loop to iterate over every index, or memcpy. I wanted to use memcpy as people said it would save space and I have a 3KB limit for my program (I want to fit it in a QR code).
I have a function where in my program where I have tried to utilize this, but when I print the results they come out as pointers. I am very confused as to why this is happening, because other people I've seen use this it turns out fine. What could i do instead? My function is here:
void ShiftBlock(int curBlock[4][2], int shiftCoords[2], int curGrid[WIDTH][HEIGHT])
{
int blockCoords[4][2] = {0};
memcpy(blockCoords, curBlock, sizeof(blockCoords));
for(int i = 0; i < 4; i++)
{
blockCoords[i][0] += shiftCoords[0];
blockCoords[i][1] += shiftCoords[1];
if (0 > blockCoords[i][0] || blockCoords[i][0] > WIDTH || 0 > blockCoords[i][1] || blockCoords[i][1] > HEIGHT || curGrid[blockCoords[i][0]][blockCoords[i][1]] != 0)
{
return;
}
}
memcpy(curBlock, blockCoords, sizeof(curBlock));
}
Arrays can't be passed as parameters so for a parameter type the first dimension of an array type is always ignored and the parameter declaration is a pointer instead. So your function type is actually:
void ShiftBlock(int (*curBlock)[2], int* shiftCoords, int (*curGrid)[HEIGHT])
I recommend to use this form because the other one is misleading.
Now you can see that sizeof(curBlock) is wrong. It's just the size of a pointer. So either use sizeof(blockCoords) or sizeof(int[4][2]) or 4 * sizeof(*curBlock).

C - Array created with malloc is larger than defined size [duplicate]

This question already has answers here:
How dangerous is it to access an array out of bounds?
(12 answers)
Program do not crash on heap overflow
(2 answers)
Closed 4 years ago.
I'm creating an array with malloc like so:
#include <stdio.h>
#include <stdlib.h>
void main(){
int * m = malloc(3 * sizeof(int));
int i;
m[0] = 1;
m[1] = 2;
m[2] = 3;
for (i = 0; i < 20; i++){
printf("%d \n", m[i]);
}
getchar();
}
As you can see the array should be the size of three integers.
I define the first three elements and then print out 20 elements from the array. but how is this possible? if malloc allocated three integers worth of memory to the array then why does the array still contain additional data past the initial three elements? maybe i am misunderstanding how malloc works, in which case how can i define an array with a strict size that will not include random data which I did not add to it?
thanks

How to remove unused space in an array [duplicate]

This question already has answers here:
Resizing an array with C
(3 answers)
Closed 5 years ago.
#define n 10
int a[n];
I wanted to declare an array globally and modify the size in other function
int main(){
int b;
printf("Enter the number of elements\n");
scanf("%d",&b);
#undef n
#define n b
for(int i = 0;i < n; i++)
scanf("%d",&a[i]);
display();
}
I modified the size in the main function
void display()
{
for(int i=0;i<n;i++)
printf("%d ",a[i]);
}
when i enter a size like 5 and enter the elements 1 2 3 4 5
the output shows 5 elements followed by 5 zeroes 1 2 3 4 5 0 0 0 0 0
how to remove the zeroes?
You can't. Once you declare an array you can't change it's size. As an alternative you can emulate this behavior perfectly using a pointer and then allocating dynamically memory and assigning the chunk address to this pointer. You can then realloc memory to incorporate this size change.
It will be something like:-
size_t sz = 10;
int *arr = malloc(sizeof *arr * sz); // sizeof(*arr)*sz (sizeof is operator)
if(!arr){
perror("malloc");
exit(1);
}
...
sz/=2; //correcting the size
int *p =realloc(arr,sizeof *arr * sz);
if(!p){
perror("realloc");
exit(1);
}
arr = p;
...
free(arr);
Also macro is not a runtime thing - it is expanded at compile time. And more over you want the array to be resized in run time not compile time. Otherwise you can set the array size to be that size from the very beginning when you wrote the code. That's why macro won't work here.
Note that arr here is not an array - it is a pointer pointing to an allocated memory (the starting address of the memory chunk that was created using malloc). Nothing else.
What you did was just changing a preprocessor constant. They are evaluated at compile time, so your redefinition is effectively pointless and takes no effect.
Not sure what you're trying to achieve here, since this array is not going to be reallocated. If you only want to limit the amount of entries you are iterating through, ditch your n and replace it with something like:
static const size_t n = 10;
static size_t num_entries = n;
Then instead of redefining n, you should just do
num_entries = b;
and later on use this to iterate through the array. However, do note that this does not reallocate the array so things are going to go terribly wrong if b is bigger than n!
If you want to reallocate the array, you're better off reading up about malloc, realloc and free. As well as some fundamental tutorials about C in the meantime, since basing on your misunderstanding of what preprocessor (#define'd variables) are, you most likely just started with C.

malloc 2d arrays in C [duplicate]

This question already has answers here:
Using malloc for allocation of multi-dimensional arrays with different row lengths
(8 answers)
Closed 9 years ago.
I have a structure to store information in a 2D array:
struct slopes {
int size;
int ** slope_array;
};
I malloc the required memory for the structure(the array has dimensions of s*s):
struct slopes * slope=malloc(sizeof(struct slopes));
slope->size=s;
slope->slope_array=malloc(sizeof(int *)*s);
int i;
for(i=0;i<s;i++) {
slope->slope_array=malloc(sizeof(int)*s);
}
But lines such as these seem to throw segmentation errors:
slope->slope_array[0][0]=3;
Can someone see what I'm doing wrong?
In your for loop, you need to initialize slope->slope_array[i], not slope->slope_array:
for (i = 0; i < s; i++) {
slope->slope_array[i] = malloc(sizeof(int)*s);
}
Note: if you had cast the return call from malloc to an int *, the compiler would have warned you about this error...
There is a simple bug in your code, in the for loop do not assign the pointer returned by malloc to slope->slope_array, but to slope->slope_array[i]
slope->slope_array[i] = malloc(sizeof(int) * s);

calculating length of array gives weird results [duplicate]

This question already has answers here:
Using sizeof with a dynamically allocated array
(5 answers)
Closed 9 years ago.
I'm trying to find out the length of an array but i get weird numbers…
#include <stdio.h>
#include <stdlib.h>
const int numOfCoordinates = 100;
typedef struct {
int x;
int y;
int counter;
} Coordinate;
Coordinate *coordinatesMainArray;
Coordinate endPoint;
Coordinate startPoint;
int main(int argc, const char * argv[])
{
endPoint.x = 8;
endPoint.y = 3;
endPoint.counter = 0;
startPoint.x = 1;
startPoint.y = 4;
coordinatesMainArray = malloc(sizeof(Coordinate) * 1);
coordinatesMainArray[0] = endPoint;
int a = sizeof(coordinatesMainArray);
int b = sizeof(coordinatesMainArray[0]);
int coordinatesMainArrayLength = (a / b);
This is my code up until the part i need the length of coordinatesMainArray.
But I get a = 8 and b = 12.
I assumed i would get two similar sizes so it shows i have one element in my array.
What am i doing wrong?
sizeof(coordinatesMainArray) gives you the size of the coordinatesMainArray variable - a Coordinate*
sizeof(coordinatesMainArray[0]) gives you the size of the first element in the coordinatesMainArray array - a Coordinate instance. sizeof(*coordinatesMainArray) would have been equivalent to this.
As an aside, there is no way to use a pointer to determine the size of an array. You'd need to store the array size separately and either pass this as well as the array pointer to other functions or guarantee that the array ends with a known terminator value (e.g. NULL)
In this case sizeof will only return the size of the coordinatesMainArray pointer (regardless of the size of its contents), because it is allocated on runtime.
sizeof(coordinatesMainArray) gives you sizeof(Coordinate *) and sizeof(coordinatesMainArray[0]) gives you sizeof(Coordinate).
First is sizeof pointer and second is sizeof array element.
When you allocate a memory with malloc it doesn't maintain the size of the allocated chunk. At least not accessible to your regular code. If you allocate memory, you have to keep track of the size yourself.
In your example you just got the size of the pointer (a) and the size of a single structure (b).

Resources