How should I make a dynamic array of 1<n<300000 - arrays

I am trying to solve a problem on a competitive programming page, and it had occurred to me that a good way to solve it would be by making a dynamic array, right now I don't care about the problem and what I want to know is how something like this could be implemented.
The idea is first they give us the number of cases (the size of the array) and then we make certain tours of that array, I would also have to apply it to a matrix of characters (an array of strings), this code that I have here works well when the input of cases is 1 <n <110, but of course, when that range is passed (it should be up to 300000 ) gives me a memory access error Process finished with exit code -1073741819 (0xC0000005), which is normal considering what I'm trying to do, I don't even know if it can, thank you very much in advance!
This is my code:
int main() {
int cases, i, j, max = 0;
while ((scanf("%d", &cases)) != EOF) {
int *victims;
victims = (int *) malloc(cases * sizeof(int));
const char **date;
date = (const char **) malloc(cases * sizeof(char));
for (i = 0; i < cases; i++) {
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
}
for (i = 0; i < cases; i++) {
scanf("%s", date[i]);
scanf("%d", &victims[i]);
}
}
}

The lines
const char **date;
date = (const char **) malloc(cases * sizeof(char));
are wrong. The element is const char*, so you have to allocate for that.
In other words, you have to allocate size of a pointer, not size of a char, for each elements.
Moreover, the objects pointed at by the elements of the array date will be modified via scanf() later, so they should be char*, not const char*.
it should be
char **date;
date = malloc(cases * sizeof(char*));
or
char **date;
date = malloc(cases * sizeof(*date));
Also the line
date[i] = (char *) malloc(10 * sizeof(char));//String max length is 10.
is wrong. You have to allocate one more element for the terminating null-character to allow 10-character strings to be stored there.
It should be:
date[i] = malloc(11 * sizeof(char));//String max length is 10.
Also note that:
You need not multiply sizeof(char) because it is defined to be 1.
Casting the results of malloc() is considered as a bad practice.

Related

allocating space for pointer to array of pointers

Good day. I have this: MAP_ITEM **map what I think is pointer to array of pointers (correct me if I am wrong please) and I have to allocate space for it. I can allocate space using malloc for 1 pointer, but have no idea how to do this. help would be really appreciated.
Here is an example, written for use with char **, but you can modify for your purposes:
char ** allocMemory(char ** a, int numStrings, int maxStrLen)
{
int i;
a = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
for(i=0;i<numStrings; i++)
{
a[i] = calloc(sizeof(char)*maxStrLen + 1, sizeof(char));
}
return a;
}
call it like this: (for array of 10 strings, each having maximum of 79 characters (leave one for NULL term)
char **arrayOfString;
arrayOfString = allocMemory(arrayOfString, 10, 80);
//
You also need to free memory created with allocMemory
void freeMemory(char ** a, int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
if(a[i]) free(a[i]);
free(a);
}
Call it like this:
freeMemory(arrayOfStrings, 10);
Import the stdlib.h
Then use the malloc function.
Where is an example for a one dimentional array:
int* my_in_array = (int*) malloc(sizeof(int) * size_of_my_array);
Note that malloc receives the number of bytes you want to allocate, so sizeof will tell you how many bytes a datatype will need (in this case an int, but it can be used for chars, structures, ...) and then I multiplicate it by size_of_my_array, wich is the number of elements of my array.
Now, just try to se this for you case.

Dynamically allocated 2 dimensional array

I am trying to build two dimensional array by dynamically allocating. My question is that is it possible that its first dimension would take 100 values, then second dimension would take variable amount of values depending on my problem? If it is possible then how I would access it? How would I know the second dimension's boundary?
(See the comments in the code)
As a result you'll get an array such like the following:
// Create an array that will contain required variables of the required values
// which will help you to make each row of it's own lenght.
arrOfLengthOfRows[NUMBER_OF_ROWS] = {value_1, value_2, ..., value_theLast};
int **array;
array = malloc(N * sizeof(int *)); // `N` is the number of rows, as on the pic.
/*
if(array == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
// Here we make each row of it's own, individual length.
for(i = 0; i < N; i++) {
array[i] = malloc(arrOfLengthOfRows[i] * sizeof(int));
/*
if(array[i] == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
}
You can use array of 100 pointers:
int *arr[100];
then you can dynamically allocate memory to each of the 100 pointers separately of any size you want, however you have to remember how much memory (for each pointer) you have allocated, you cannot expect C compiler to remember it or tell it to you, i.e. sizeof will not work here.
To access any (allowed, within boundary) location you can simply use 2D array notation e.g. to access 5th location of memory allocated to 20th pointer you can use arr[20][5] or *(arr[20] + 5).
I believe the OP wants a single chunk of memory for the array, and is willing to fix one of the dimensions to get it. I frequently like to do this when coding in C as well.
We all used to be able to do double x[4][]; and the compiler would know what to do. But someone has apparently messed that up - maybe even for a good reason.
The following however still works and allows us to use large chunks of memory instead of having to do a lot of pointer management.
#include <stdio.h>
#include <stdlib.h>
// double x[4][];
struct foo {
double y[4];
} * x;
void
main(int ac, char * av[])
{
double * dp;
int max_x = 10;
int i;
x = calloc(max_x, sizeof(struct foo));
x[0].y[0] = 0.23;
x[0].y[1] = 0.45;
x[9].y[0] = 1.23;
x[9].y[1] = 1.45;
dp = x[9].y;
for (i = 0; i < 4; i++)
if (dp[i] > 0)
printf("%f\n", dp[i]);
}
The trick is to declare the fixed dimension in a struct. But keep in mind that the "first" dimension is the dynamic dimension and the "second" one is fixed. And this is the opposite of the old way ...
You will have to track the size of your dynamic dimension on your own - sizeof can't help you with that.
Using anonymous thingies you might even be able to git rid of 'y'.
Using a single pointer:
int *arr = (int *)malloc(r * c * sizeof(int));
/* how to access array elements */
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count; //count initialized as, int count=0;
Using pointer to a pointer:
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
In this case you can access array elements same as you access statically allocated array.

Initialising 2d dynamic Array

I am new to C and trying to initialise a 2D array. I need both columns of the array to be char *, as they will contain string values.
I have it working with the array storing ints but for some reason, when I try to store string values when it prints it displays (null). Below is the code for how I am initialising and storing the data as an int (This appears to be working).
int **array;
int row = 0;
array = malloc(2 * sizeof(int*));
int i;
for (i = 0; i < 2; i++)
{
array[i] = malloc(2 * sizeof(int));
}
array[0][0] = i;
array[0][1] = i;
printf("array[0][0]: %i\n", array[0][0]);
Below is how I am doing the above but using string values instead.
char **array;
int row = 0;
array = malloc(2 * sizeof(char*));
int i;
for (i = 0; i < 2; i++)
{
array[i] = malloc(2 * sizeof(char*));
}
array[0][0] = "Test[0][0]";
array[0][1] = "Test[0][1]";
printf("array[0][0]: %s\n", array[0][0]);
Thanks for any help you can provide.
You have the wrong level of pointer indirection, which is over-complicating things.
I think it would be easier for you if you thought of the array as an array of structures, each structure holding two pointers:
struct row {
char *column1;
char *column2;
};
then it's (hopefully) clearer that once you've allocated an array of struct row, you have two pointers in each row, you don't need to allocate room for the pointers themselves.
const size_t num_rows = 1;
struct row * rows = malloc(num_rows * sizeof *rows);
if(rows != NULL)
{
rows[0].column1 = "row 0, column 1";
rows[0].column2 = "row 1, column 2";
}
Note that this uses string literals, otherwise you might need to allocate room for the strings to be stored, depending on where the data comes from.
The num_rows value could of course come from anywhere in your program, I'm just trying to illustrate what controls the number of rows memory is allocated for.
Save yourself the trouble and don't use 2D arrays in C. It's more convenient to use 1D arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
const int nstrings = 2;
const int width = 20; //width of maximum string.
char* array = (char*)malloc(sizeof(char)*nstrings*width);
strcpy(&array[0*width],"Test[0][0]");
strcpy(&array[1*width],"Test[1][0]");
printf("string 0: %s\n", &array[0*width]);
printf("string 1: %s\n", &array[1*width]);
free(array);
}

How to empty a 2d char array in C?

I am still new with C and I am trying to empty a 2d char array. Here is the declaration:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = (char*) calloc (strlen(buf), sizeof(char*));
}
Here is where I try to empty it:
void make_empty(char **arg_array)
{
int i;
for(i = 0; i <= BUFSIZ; i++)
{
arg_array[i][0] = '\0';
}
return;
}
Any help is appreciated
So, am I doing it right because this seems to give me segfaults when I try to add data to the array again and then print it?
Empty is just to have it empty - how can I explain more? lol
Try this:
void make_empty(char **arg_array, int rows, int cols)
{
int i,j;
for(i = 0; i <rows; i++)
{
for(j=0; j<cols;j++)
{
arg_array[i][j] = '\0';
}
}
return;
}
Where rows is number of rows and cols number of cols of your array.
P.S. This function clears the whole array as you should always do. As I commented before, putting '\0' as a first char in string does not clear the whole row, it only makes the rest of it ,,invisible'' for functions like printf. Check this link for more information: http://cplusplus.com/reference/clibrary/cstdio/printf/
There is no need to empty it. Often in C, memory allocation is done with malloc which simply returns to you a block of memory which is deemed owned by the caller. When calloc is called, as well as returning you a block of memory, the memory is guaranteed to be initialized to 0. This means for all intents and purposes it is already 'empty'.
Also I'm not quite sure if your code does what you are intending. Let me explain what it does at the moment:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
This line is simply wrong. In C, there is no need to cast pointers returned from calloc because they are of type void *, which is implicitly casted to any other pointer type. In this case, you are storing it in a char type which makes no sense. If you do this:
char ** arg_array = calloc(strlen(buf), sizeof (char**));
Then it allocates an array of pointers of strlen(buf) length. So if buf is "hello" then you have now allocated an array which can store 5 pointers.
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = calloc (strlen(buf), sizeof(char*));
}
Again, I have removed the redundant cast. What this does is populates the array allocated earlier. Each index of the array now points to a char string of strlen(buf) * sizeof(char *) length. This is probably not what you want.
Your question is more clear to me now. It appears you want to remove the strings after populating them. You can do it two ways:
Either free each of the pointers and allocate more space later as you did before
Or set the first character of each of the strings to a null character
To free the pointers:
for(i = 0; i<(strlen(buf)); i++)
{
free(arg_array[i]);
}
To set the first character of each string to a null character:
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i][0] = '\0';
}
That is the same code as what you have originally and should be fine.
As proof, the following code will run without errors:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char * buf = "hello";
char ** arg_array = calloc(strlen(buf), sizeof (char**));
unsigned int i;
for(i = 0; i < strlen(buf); i++) {
arg_array[i] = calloc(strlen(buf),
sizeof(char *));
}
for(i = 0; i < strlen(buf); i++) {
arg_array[i][0] = '\0';
}
for(i = 0; i < strlen(buf); i++) {
free(arg_array[i]);
}
free(arg_array);
return EXIT_SUCCESS;
}
If your code is segfaulting, the problem is coming from somewhere else. Did you overwrite the arg_array variable? Are you sure BUFSIZE is equal to strlen(buf)?

C dynamic string array

I have char * lines[1000] string that can hold 1000 characters. How to create 100 arrays of that string. I get error with this code down.
char * lines[1000];
lines = (lines*)malloc(100 * sizeof(lines));
main.c:19:20: error: expected expression before ')' token
The simplest way is:
char lines[100][1000];
Alternatively:
char* lines[100];
int i;
for (i = 0; i < 100; i++) {
lines[i] = malloc(1000);
}
...
for (i = 0; i < 100; i++) {
free(lines[i]);
}
The latter is a bit more flexible in that -- with minor modifications -- it permits you to allocate a different amount of memory for every string.
It looks like you want an array strings, each string holding at most 1000 characters. There are some issues with your code.
You've declared an array of char *s but what you really want is a pointer to an array of chars. For that, your declaration should be
char (*lines)[1000];
On the other hand, you shouldn't forget about the NULL bytes at the end of strings, and should probably instead declare
char (*lines)[1001];
To set the pointer, you'll want to use
lines = (char (*)[1001]) malloc(100 * sizeof(char[1001]));
or
lines = (char (*)[1001]) malloc(100 * sizeof(*lines));
the latter working because, with lines a pointer to an array of chars, *lines is a char[1001]. Remember to make sure you didn't get a NULL pointer back.
At the end, you should free the memory you've malloced with
free(lines);
You can write a for-loop as:
char * lines[1000];
int i = 0;
for (i = 0; i < 1000; i++)
{
lines[i] = (char*)malloc(100 * sizeof(lines));
}
Don't forget to free-up the memory pointed by all the pointers
for (i = 0; i < 1000; i++)
{
free(lines[i])
}
Why don't you create a 2 dimensional array?

Resources