malloc 2d arrays in C [duplicate] - c

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);

Related

Using pointer of pointer to reference a matrix [duplicate]

This question already has answers here:
Why can't we use double pointer to represent two dimensional arrays?
(6 answers)
Closed 3 years ago.
I am very new to C, and I am trying to get a int **data to represent a matrix of integers.
I first created an array of arrays, then I tried referencing the pointer of pointer to that array like so:
int **pointer;
int data[num_rows][num_cols];
pointer = (int**) data[0];
However I get a warning: cast to pointer from integer of a different size.
Can someone please help me understand what is going on, and how can I assign an array to int **pointer? (I have to use the double pointer)
The line int data[num_rows][num_cols]; does not actually declare an "array of arrays!" Rather, it declares a single array with two dimensions - in memory, this will be a single block of data, of size num_rows x num_cols x sizeof(int).
To get an "array of arrays" that you can access using a 'double pointer', you generally have to use the malloc function. Something like the following:
int **pointer = malloc(num_rows * sizeof(int*)); // allocate an array of pointers
for (int i = 0; i < num_rows; ++i) {
pointer[i] = malloc(num_cols * sizeof(int)); // allocate each row array
}
You can then access any [row][column] element via the double pointer:
pointer[row][column] = 1234;
When you've finished with the array(s), be sure to free the memory, like this:
for (int i = 0; i < num_cols; ++i) {
free(pointer[i]); // free each row array
}
free(pointer); // free the array of arrays
Alternatively, given your int data[num_rows][num_cols]; you could avoid the malloc calls inside the for loop, as follows:
int **pointer = malloc(num_rows * sizeof(int*)); // allocate an array of pointers
for (int i = 0; i < num_rows; ++i) {
pointer[i] = &data[i][0]; // Assign a pointer to the beginning of each row
}
Feel free to ask for further clarification and/or explanation.

getting size of array/vector in c [duplicate]

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.

String array not getting correct values in a function [duplicate]

This question already has answers here:
Weird incompatible pointer type error
(2 answers)
Isn't double[][] equivalent to **double?
(9 answers)
Closed 4 years ago.
I made an array of strings(matrix of chars), and I am trying to make a function that will read the strings and store them in an array. This is the function I made:
void input_strings(char **array, int n){
for (int i = 0; i < n; i++) {
scanf("%s",&array[i]);
printf("%s \n",&array[i]);
}
}
I added the printf() to verify that the input was doing alright in the function, and indeed printf() does return what I inputed previously using scanf().
But when I try to access the array fields after the input function, I get random garbage on my screen. This is what my main function looks like:
int main() {
char string_array[n][stringsize];
input_strings(&string_array, n);
printf("%s",&string_array[1]);
return 0;
}
n and stringsize are global variables large enough. Why does the program print out ���� instead of the string I inputed?
Edit: Edited the matrix from char** string_array[n][stringsize] to charstring_array[n][stringsize], the problem still persists.
Edit 2: So the problem was that a char matrix was incompatible with the function parameters. I fixed the issue by declaring the string_array in the following way.
char ** string_array = (char **) malloc(sizeof(char*)*n);
for (int i = 0; i < n; ++i) {
string_array[i] = (char *) malloc(sizeof(char)*stringsize);
}
Also when declared this way, the function call should look like this:
input_strings(string_array, n);
Yeah, the correct way to pass the address is simply string_array. So, input_strings(string_array, n); or even input_strings(&(string_array[0][0]), n); which is the address of the first column of the first row.

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

Passing a pointer to an array and allocating memory [duplicate]

This question already has answers here:
Is it possible to allocate array inside function and return it using reference?
(3 answers)
How can I allocate memory for array inside a function
(5 answers)
How to use pointers to allocate an array inside another function
(2 answers)
Allocate memory 2d array in function C
(8 answers)
Closed 5 years ago.
I'm trying to pass a pointer from main to a function I wrote, which suppose to allocate memory with the size integer and receive input from the user.
Now I know I'm doing something wrong because the pointer doesn't change back in the main function. could someone tell me what exactly I did wrong?
int rows, *newCol=NULL // the pointer inside main();//rows is the size of the array.
the function:
void buildArr(int *newCol, int rows);
void buildArr(int *newCol, int rows)
{
int i;
newCol = (int*)malloc(sizeof(int)*rows);
for (i = 0; i<rows; i++)
{
printf("enter the value of the newCol:\n");
printf("value #%d\n", i + 1);
scanf("%d", &newCol[i]);
}
}
The pointer shouldn't change in the callee. C is pass by value.
Pass the address of the pointer variable
Call it like
buildArr(&newCol,rows);
...
...
void buildArr(int **newCol, int rows)
{
int i;
*newCol = malloc(sizeof(int)*rows);
...
scanf("%d", &(*newCol)[i]);
}
// nothing is returned.
}
Or return the address of the allocated chunk
newCol = buildArr(newCol, rows);
...
...
int* buildArr(int *newCol, int rows)
{
int i;
newCol = malloc(sizeof(int)*rows);
...
scanf("%d", &newCol[i]);
...
return newCol;
}

Resources