Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
EDIT
i want to create a program which will work with a long number. the user will be asked to input the length (in digits) of the number they want to work with. there is a
char aa [the chosen length goes here];
where in the [] brackets should be the value that was input by the user.
it could look like this:
"please input the length in digits"
there is a scanf and you input, for example, 17
then a char aa [17] is created
i just don't know how can i use a variable to input a value in the [] brackets defining the memory size that is saved for a char
You want a variable lenght array, you can do it like this:
int digit;
scanf("%d", &digit);
char test [digit+1];
This will work for your purposes. Usual restrictions of course apply.
Keep in mind this functionality was only added in the C99 Standard. So if your compiler supports only previous standards, this will not work.
However, the more appropriate and better practice method to use is to use malloc to allocate the char array properly
int digit;
scanf("%d", &digit);
char* aa = malloc(digit + 1);
//Do what you want with the char array aa
free(aa);
Do not forget to check the result of malloc() against NULL and free the variable afterwards to prevent memory leaks if you want to do this.
Also be aware that the "array" malloc returns is actually just a pointer, which is very relevant when trying to determine the size/length of it, using sizeof:
char real_array[5];
sizeof(real_array); // == 5
char* dynamic_array = malloc(5);
sizeof(dynamic_array) // == sizeof(char*) == on most systems = 8
What you are asking is variable length array which is possible in C99. See Dynamic array allocation on stack in C
Look at the following code snippet:
int size;
scanf("%d", &size);
char array[size + 1]; //1 extra space to accommodate `\0` character
printf("%d\n", sizeof(array));
This will print sizeof(char) * (size+1) proving the array creation dynamically.
The only disadvantage of this way over malloc way is after declaring an array (which is of user-input size) you can't change the array size in program. It's fixed.
While using dynamic memory allocation (malloc, calloc) you can change the array size whenever possible in a program by freeing the memory.
Since variable length array is possible in c99 you may have to use gcc --std=c99 -c program.c to compile your source code. For other compiler refer the proper compiler manual.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
the code is from C the code is written below:-
int main(){
char* time = (char *)malloc(10240 * sizeof(char));
scanf("%s",time);
return 0;
}
Error:
Because there is no prototype in scope for malloc the compiler interprets the result (of type void*) as type int.
Then it converts that value to type char* and assigns the resulting (meaningless) value to time.
Then, still using the meaningless value, it attempts to store there a value read and interpreted as an integer from standard input.
It then exits without doing anything more. Particularly it doesn't use the value read or release the memory (probably) allocated earlier.
it has first reserved memory dynamically from the heap by using malloc function, then it is scanning a string. pay attention to the format fo %s conversion specifier: the argument related to it is a pointer.(not for example time[0].)
don't forget that the memory should be free after the work is done
syntax: free (time);
char* time = (char *)malloc(10240 * sizeof(char));
Here, you use malloc() to allocate 10240 * sizeof(char) blocks of memory for you. sizeof(char) is equal to 4 bytes, so you are allocated 10240 * 4 = 40960 blocks of memory as int by default, as you have not specified any prototype in scope (seen as void*) for malloc()
You then cast the memory space to a char * and have *time point the first block in that memory allocated to you.
scanf("%s",time);
In this line, you try to store a value read as integer input from scanf() in time. Your format specifier is wrong here.
The program then terminates, without freeing the memory you allotted in it, and without doing anything with the inout you took with scanf().
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I know that we cannot dereference a void pointer until and unless we typecast it.
void *ptr = call_a_function();
printf("%d",*(int *)ptr);
This informs the datatype of element(in this case its integer) to the compiler so that it can dereference the amount of space required for it(in this case its 4 bytes).
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
In other words is there a way to tell the compiler how many bytes of memory to read by providing the number of bytes to extract and not the datatype??
EDIT -
I needed to swap the contents of two void * pointers.
Got influenced by the regular way of swapping two values i.e storing the value of one pointer in a temporary variable and then proceed with swapping.
Was trying to attempt the same thing without knowing the datatype but only its size( since the function with this swap code accepts size of variable as one parameter ). However after reading the answers and comments, got to realize that I really dont need to dereference it. Probably memcpy is the correct way to go.
Suppose I dont know the final datatype, however I know the size of datatype. Can I still dereference it using only the size(4 bytes) and not the datatype(not using int)??
Since you cannot deduce or assume the data type, you can't dereference the pointer once to get the complete object. However, you can extract each byte and use it anyway you want.
void *ptr = call_a_function();
unsigned char* cptr = (unsigned char*)ptr;
for (int i = 0; i < num_bytes; ++i )
{
unsigned char c = cptr[i];
// Use c
}
In this case, the whole is not the sum of its parts. Casting not only provides the compiler with the size of the data but also how that data is to be interpreted. Suppose you get 4 bytes, this could be a string of three characters with a NULL byte or a signed integer, which could be encoded in big-endian or little-endian depending on the platform. So knowing the size is not sufficient to properly handle the data even if you could tell the compiler how many bytes to read/dereference.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Old Test
I'm going over a test I took and am trying to figure out what the answer was to these questions. I was wondering if anyone could help me? As you can probably see I did not really understand how to answer them at the time but I would like to learn. I believed the answer has something to do with Malloc, but was unsure exactly how.
Thank you!
Edit : Is this how you do it?
#include <stdio.h>
#include <stdlib.h>
float* func();
int main(void)
{
float *x;
x = func();
printf("%f\n", *x);
return 0;
}
float* func(void){
float * z;
z = malloc(sizeof(float));
* z = 11.2;
return z;
}
malloc is related to allocating memory.
When we talk about array and pointer in c, we can seperate it into static array and dynamic array. For static array, we use array, for example,
char arr[10];
which means declare char type array named arr with length of 10.
For Dynamic array, we use pointer, for example, char *arr. This means char type pointer of arr. Pointer is very flexible; therefore, you must command to use it properly.
Assume
char *arr = (char *) malloc (sizeof (char) * 10);
This means you have a pointer and will allocate the memory with the size of char type with length of 10 you can also re allocate memory with realloc with different length. At the end of using it you must
free(arr);
To add, this is benefit of C language and I believe it is harder to use than other languages but more flexibility. On the other hand, you must be very very careful using it. Unproperly used pointer could cause entire software failure.
As float z is defined locally in fucntion, it's allocated on stack.
As a result it memory allocation is destroyed when function exits.
As a result you will have a runtime error cause you are accesing a memory that do not belongs to you.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I declared an array in C of size 150X150X150. Upon compiling the program to get an array of same size,the compiler gave no errors or warnings. but when I tried running it, the program stops responding.
void main(){
int i,j,k;
char giv[150][150][50],tar[150][150][50];
for(int i=0;i<150;i++)
{
for(j=0;j<150;j++)
{
for(k=0;k<50;k++)
cin>>giv[i][j][k];
}
}
}
Is there any way that I can create an array of 150*150*150 without causing a run time error?
EDIT: I know multidimensional arrays work. This is not a compilation error. Its a run time error, whose cause was I am not able to pinpoint.
You just declared two arrays on the stack.
Each array has size: 150 * 150 * 50 bytes, or about 1.1MB.
So you are asking for 2.2MB from the stack.
Typical stack size is about 1 or 2MB.
So I expect you're getting a StackOverflow Exception.
(kinda appropriate for this site)
You could allocate the arrays on the heap:
#include <stdlib.h> /* for malloc()/calloc() */
#include <stdio.h> /* for perror() */
...
char (*pgiv)[150][150][50] = malloc(sizeof *giv);
char (*ptar)[150][150][50] = malloc(sizeof *tar);
If you want to have the arrays' elements initialised to all 0s on allocation use calloc() as follows:
char (*pgiv)[150][150][50] = calloc(1, sizeof *giv);
char (*ptar)[150][150][50] = calloc(1, sizeof *tar);
Also test wether the allocation succeed or not:
if (NULL == pgiv)
perror("malloc() failed");
if (NULL == ptar)
perror("malloc() failed");
Address an element by doing for example:
(*pgiv)[0][1][2] = 123;
Note that pgiv and ptar are actually pointers (to an array). That's why they need to be dereferenced (using the dereference operator *) before being used like an array.
It seems that the problem is with the limit of the stack memory.
In C++ you could use for example standard container std::vector.
In C you could allocate these arrays yourself dynamically.
The simplest way is either to declare these arrays globally that is outside any function or specify keyword static that the arrays had static storage duration. For example
static char giv[150][150][50],tar[150][150][50];
As for other languages then for example Java and C# allocate arrays in the managed heap. It keeps in the stack only a reference to the array.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What is purpose of using sizeof using malloc in C?
Why its necessary?
I mean we can use sizeof but we already know the size(=1000 bytes) what we are allocating in memory?
I am beginner in C so. This might be a very obvious question.
DataTypes And Memory Matter
The answer is in the data types. While you know how many objects you want to allocate memory for, you may not want to go through the trouble of mentally computing their size.
So Does Maintainability
Also, what if the composition of these changes later? Then you're screwed and have to edit everything.
So that's irrelevant in your example, without context. But in the case where you want to allocate memory for more complex things (say, a struct with a number of fields), it does become quite important and useful.
Example 1 (not so important here):
char *s = malloc(100 * sizeof(char));
But hey, it's just chars, it's fine, you could have done that:
char *s = malloc(100);
Generally works. But shooting yourself in the foot, as you'll see below.
Example 2 (matters a bit already):
int *i = malloc(100 * sizeof(int));
Sure, you could have written that:
int *i = malloc(100 * 4);
That is, assuming you develop for just one architecture you know pretty well.
Example 3 (starting to matter quite a bit!):
typedef struct s_listelement{
int dataitem;
struct s_listelement *link;
} t_listelement;
t_listement *le = malloc(sizeof(t_listelement));
Now imagine that linked-list item's structure contains a bunch of other fields...
Would you want to trust sizeof(), or go have fun and do the math yourself?
Suppose you want to allocate memory for storing ints. Your initial guess will be, okay I need to have n integers and each integer requires x bytes. So space will be n*x bytes.
But actually this x depends on architecture. It maybe 16 bit, 32 bit, etc. So to make your code able to work in different environments, it is recommended to use n*sizeof(int) instead of n*x.
For example, if you need to allocate space for 10 integers:
int *p=malloc(sizeof(int)*10);
What happens if you change the size of mallocated?
You will have to 1) calculate again the new size (letting aside multiple target architectures problems, where you will have to calculate the new size in each target), 2) search for all malloc(1000), make sure it refers to mallocated (which might be not obvious) and replace with new size.
You don't have any of these 2 problems using sizeof. Thus using sizeof leads to a more maintainable and readable code.