I am struggling with an algorithm to print numbers between 1 and a dynamic variable n into an int.
int n = // dynamic value
int i = 0;
int output[n];
for(i = 0; i < n; i++) {
output[i] = i;
}
However, as n is dynamic, the code won't compile.
Any help would be much appreciated - thanks in advance.
You need to allocate a buffer, or dynamic-sized array, with malloc:
int n = // whatever
int i = 0;
int* output = NULL;
// Allocate the buffer
output = malloc(n * sizeof(int));
if (!output) {
fprintf(stderr, "Failed to allocate.\n");
exit(1);
}
// Do the work with the array
for(i = 0; i < n; i++) {
output[i] = i;
}
// Finished with the array
free(output);
output is a pointer to the beginning of the buffer you allocated, and you can treat it as an array of n ints.
When you're finished with the array, you need to de-allocate the memory with free.
This should work:
int n = // whatever
int i = 0;
int* output = (int*)malloc(sizeof(int)*n);
for(i = 0; i < n; i++) {
output[i] = i;
}
Don't forget to free(output); when you don't need it anymore.
EDIT: Made it C.
If 'n' is changing during runtime, then you could use malloc like suggested in the comments. Then check if you need more space, then automatically realloc more space should it be needed
Related
I followed few examples on this forum, but it seems like my program still keeps crashing at some point.
All i want to do is just use a void function for memory allocation.
void alloc(int ***matrix, int n)
{
int i = 0;
for( ; i < n; i++)
{
(*matrix)[i] = (int*)malloc(n * sizeof(int));
}
i = 0;
for( ; i < n; i++)
{
int j = 0;
for( ; j < n; j++)
{
(*matrix)[i][j] = i * j;
}
}
}
//-------------------------------------------------------------------
int main()
{
int n;
int **matrix_pp;
printf("Enter n: ");
scanf("%d", &n);
alloc(&matrix_pp, n);
free(matrix_pp);
return 0;
}
You try to use (*matrix)[i] before it's been allocated. Add:
(*matrix) = malloc(n * sizeof(**matrix));
before your for loop.
Note two things here:
1) Don't cast the result of malloc,
2) use sizeof(*pointer) instead of explicitly writing out the type; this way, if you decide to change the type later, it will still work.
Further, you will need to free all of the allocations you have in a loop as a loop as well; otherwise, you have a memory leak.
I'm trying to free the malloc that is generated with a not fixed number of arrays.
char ** get_moves(){
// some code
char **moves = malloc(sizeof(char *) * k); // 'k', could ranges between 1~9
if (!moves){
return NULL;
}
for(int i = 0; i < k; i++){
moves[i] = malloc(82);
if (!moves[i]) {
free (moves);
return NULL;
}
// more code
return moves;
}
int main(){
//some code
char **res = get_moves(some_input);
//more code
for (int i = 0; i < (sizeof(res)/sizeof(res[0)); i ++){
free(res[i]);
}
free(res);
}
In one of the inputs to get_move, res should have 2 arrays but the sizeof(res)/sizeof(res[0) gives me just 1.
How is the proper way to handle this?
The only way is to keep track of the element count of the array, if you don't want to pass it to every function when passing the array, you can combine both pieces of information in a struct, like here
#include <stdlib.h>
struct ArrayOfStrings
{
int count;
char **data;
};
struct ArrayOfStrings get_moves()
{
struct ArrayOfStrings result;
char **moves;
// some code
result.count = 0;
result.data = malloc(sizeof(char *) * k); // 'k', could ranges between 1~9
if (result.data == NULL)
return result;
result.count = k;
moves = result.data;
for (int i = 0; i < k; i++)
{
moves[i] = malloc(82);
if (moves[i] == NULL)
{
/* also free succesfully allocated ones */
for (int j = i - 1 ; j >= 0 ; --j)
free(moves[j]);
free(moves);
}
result.count = 0;
result.data = NULL;
return result;
}
// more code
return result;
}
int main(){
//some code
struct ArrayOfStrings res = get_moves(some_input);
//more code
for (int i = 0; i < res.count ; i ++)
free(res.data[i]);
free(res.data);
return 0; // you should return from main.
}
sizeof is not for the length of an object's content but for the size of a data type, it is computed at compile time.
So in your case
sizeof(res) / sizeof(res[0]) == sizeof(char **) / sizeof(char *) == 1
since sizeof(char **) == sizeof(char *) it's just the size of a pointer.
sizeof(res)
Returns the sizeof(double-pointer);
So if you intend to get the number of pointers stored then you might not get this by doing what you are doing.
You need to do something like
for(i=0;i<k;i++) /* As I see you are allocating k no of pointer Keep track of it*/
free(res[i]);
free(res);
res is in fact not an array of arrays of char type. Instead it is a pointer to pointer to char type. sizeof(res) will give you the size of char**. You need to keep track of the number of allocations.
Since the maximum number of arrays to allocate is small (9), you can simplify your code by allocating the maximum number. Fill the unused elements with NULL:
#define MAX_K 9
char **moves = malloc(sizeof(char *) * MAX_K);
for(int i = 0; i < k; i++){
...
}
for(int i = k; i < MAX_K; i++){
moves[i] = NULL;
}
To deallocate, just ignore the NULL pointers:
for (int i = 0; i < MAX_K; i ++){
if (res[i])
free(res[i]);
}
free(res);
I want to define a two dimensional array as a global variable:
int visited[nbVertices][nbVertices];
but the problem that I have to scan the "nbVertices" from a file. is there anyway to fix this problem ?
I think it may be fixed by using pointers, but I don't know how to do it.
So, while we're at it: you don't need the array to be global. Hence, you can just use variable-length arrays and pass the array to all the functions that need it:
void printArray(int n, int k, int arr[n][k])
{
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
printf("%6d", arr[i][j]);
}
printf("\n");
}
}
int main()
{
// get user input in the format "n" <space> "k"
char *end;
char buf[LINE_MAX];
if (!fgets(buf, sizeof buf, stdin))
return -1;
// create array, fill it with random stuff
int n = strtol(buf, &end, 10);
int k = strtol(end, NULL, 10);
int a[n][k];
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
a[i][j] = random();
}
}
// print it
printArray(n, k, a);
return 0;
}
Use malloc.
Your code might look something like this:
// somewhere in file, global
int **visited;
// somewhere in your code, when you read nbVertices
visited = malloc(sizeof(int*) * nbVertices);
for(size_t i = 0; i < nbVertices; i++)
visited[i] = malloc(sizeof(int) * nbVertices);
there shouldn't be any major differences using visited
I want to define a 2D array of very big size. But it is giving me segmentation fault?
#include <stdio.h>
int main () {
int i;
int temp[4000][5000];
for (i = 0; i < 5; i++)
{
printf ("Hello World\n");
}
}
Can anyone please suggest me some other way? Is there some problem with memory initialization? Thanks in advance
You can allocate the whole table in only one array but you won't be able to access array data with indices using two square brackets:
int * temp = malloc(4000*5000*sizeof(int));
to access the element (i,j) where previously you wrote temp[i][j], now you should now compute the index the following way:
temp[i*5000+j];
and do not forget to free the memory allocated for your table afterward:
free(temp);
int temp[4000][5000];
That's a VERY BIG array, way bigger than the normal size of stack, you get a segmentation fault because of stack overflow. Consider using dynamic allocation instead.
You need to use dynamic allocated arrays for such big arrays.
Try:
int* temp[4000];
for(i = 0; i < 4000; ++i) temp[i] = malloc(5000 * sizeof(int));
...
for(i = 0; i < 4000; ++i) free(temp[i]).
Whole program with error checking:
int main () {
int i, j;
int* temp[4000];
for (i = 0; i < 4000; ++i)
{
temp[i] = malloc(5000 * sizeof(int));
if (temp[i] == NULL)
{
for (j = 0; j < i; ++j) free(temp[i]);
exit(1);
}
}
for (i = 0; i < 5; i++)
{
printf ("Hello World\n");
}
for (i = 0; i < 4000; ++i) free(temp[i]);
}
Here you can find function which would use single malloc call to allocate two dimension array.
And simpler version of my own:
int main () {
int i, j;
int* temp[4000];
int* array = malloc(4000 * 5000 * sizeof(int));
if (malloc_tmp == NULL) exit(1);
for (i = 0; i < 4000; ++i)
{
temp[i] = array + (i * 5000);
}
for (i = 0; i < 5; i++)
{
printf ("Hello World\n");
}
free(temp[0]);
}
In debugging my program with Valgrind, I have discovered a memory leak despite what I thought were effective calls to free. First, the code that is allocating the memory and storing it:
row = malloc(sizeof(Row));
row->columns = malloc(sizeof(char*) * headcnt);
row->numcol = 0;
...
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row));
rows[rowcnt++] = *row;
The code responsible for attempting to free the memory:
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
for (j = 0; j < rows[i].numcols; j++){
free(rows[i].columns[j]);
}
free(&rows[i]);
}
free(rows);
exit(0);
}
The declaration of Row:
typedef struct {
char** columns;
unsigned short int numcol;
} Row;
Row* rows = NULL;
Worse still, this program sometimes causes a glibc error at free(&rows[i]) that complains of a double free. I am new to C, and would appreciate any pointers (ahem) someone might have.
Doing rows[rowcnt++] = *row; effectively makes a copy of the memory you allocated. Your array rows should be an array of pointers. Also like Oli Chalesworth pointed out, you free for columns should be a single free for all the columns.
rows = malloc(count * sizeof(Row*)); // This is probably done somewhere
row->columns = malloc(sizeof(char*) * headcnt);
row->numcol = 0;
...
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row*));
rows[rowcnt++] = row;
Now if your cleanup
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
free(rows[i]->columns);
}
free(rows);
exit(0);
}
Every call to malloc (or realloc) must be matched with a corresponding call to free. If you dynamically allocate an array thus:
int *p = malloc(sizeof(int) * NUM);
You free it like this:
free(p);
Not like this:
for (int i = 0; i < NUM; i++)
{
free(p[i]);
}
It appears that you are doing this incorrectly. I suspect that your cleanup code ought to be:
void cleanUp(){
int i = 0;
int j = 0;
for (i = 0; i < rowcnt; i++){
for (j = 0; j < rows[i].numcols; j++){
free(rows[i].columns[j]); // Free whatever rows[i].columns[j] points to
}
free(rows[i].columns); // Matches row->columns = malloc(sizeof(char*) * headcnt);
}
free(rows); // Matches rows = realloc(rows, (rowcnt+1) * sizeof(Row));
exit(0);
}
Also, there is no way to match the row = malloc(sizeof(Row));. I suspect that your allocation code ought to be:
row->numcol = colcnt;
rows = realloc(rows, (rowcnt+1) * sizeof(Row));
rows[rowcnt].columns = malloc(sizeof(char*) * headcnt);
rows[rowcnt].numcol = 0;
rowcnt++;
Maybe I'm being dense, but isn't this totally unnecessary? All of your memory will be released as soon as the program exits, anyway.