Why am I getting an "invalid initializer error" for the below code?
#include<stdio.h>
#include<malloc.h>
int main(){
int i = 2;
int j;
for(j = i ; j < 20; j++){
char *p[5] = malloc(20 * sizeof(char));
int len = 0;
p[0] = 'a';
}
return 0;
}
You have an Array of Pointers, and you're asigning only one Pointer to it:
char *p[5] = malloc(20 * sizeof(char));
Use this instead:
char *p = malloc(20 * sizeof(char));
If you actually want an Array of Pointers, but only set the first of them, this should be your code:
char *p[5] = {malloc(20 * sizeof(char))};
(Or, even better: char *p[5] = {0}; p[0] = malloc(20 * sizeof(char));)
If this is what you want, you have to asign the letter 'a' differently - use *(p[0]) = 'a'; instead.
Furthermore: you don't free your memory anymore. You should use free(p); to do this, otherwise it's possible that your program consumes more and more memory.
For small programs, this is no problem, because the OS frees the memory anyways after the Program has been closed.
But it's bad practice, and the reason for lots of bad software.
Related
HI I'm getting a segfault with this code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
char **array;
int i = 0;
array = (char **)malloc(sizeof(char *) * 20);
for (i = 0; i < 20; i++)
{
array[i] = (char *)malloc(sizeof(char *) * 20);
array[i] = "____________________";
}
array[0][0] = '2';
return(0);
}
What am I doing wrong ?
I'm very confused when I need to modify 2d arrays, what are my best options here ?
Thanks a lot.
You get a segfault because with array[i] = "____________________"; you let point each array[i] to a string literal. Note that you do not copy the contents of the literal but let array[i] directly point to it. Consequently, with array[0][0] = '2' you are altering a string literal then, which is undefined behaviour (very likely to become apparent as a segfault in this case).
Use strcpy(array[i],"____________________); instead.
BTW: write array[i] = malloc(sizeof(char) * (20+1)); (note the sizeof(char) instead of sizeof(char*) here and the +1 for the string termination character).
So I got this question from a competition website and I am completely puzzled. Here it is:
Which of the following memory allocation code for p[10][10] confirms perfectly to classical definition of an array? The options are:
char **p;
int i;
p = (char**)malloc(10*sizeof(char*));
*p = (char*)malloc(10*sizeof(char));
for(i = i; i<10; i++)
p[i] = p[0] +10*i;
char **p;
int i;
p = (char**)realloc(p, 10*sizeof(char*));
*p = (char*)realloc(p, 10*sizeof(char));
for(i = i; i<10; i++)
p[i] = p[0] +10*i;
char **p = NULL;
int i;
p = (char**)malloc(10*sizeof(char*));
*p = (char*)malloc(10*sizeof(char));
for(i = i; i<10; i++)
p[i] = (char*)realloc(p[i-1], 10*i*sizeof(char));
char **p;
int i;
p = (char**)malloc(10*sizeof(char*));
for(i = i; i<10; i++)
p[i] = (char*)malloc(10*sizeof(char));
I am completely puzzled. Any ideas are most welcome. Thanks.
EDIT: If none of them are are correct, what would be the correct implementation? A bit of explanation is most welcome as I am preparing for aa competitive exam that requres these skills which ask questions like this (most of which has obvious 'side effects' :( ). Also edited the typos.
None. This one does:
char (*p)[10] = malloc(10*sizeof(*p));
Explanation:
p is declared as a pointer to an array of ten chars. Since it points to an array, sizeof(*p) returns the size of that array, which is 10. So, the malloc() call allocates memory for ten such arrays, i. e. 100 bytes.
Now, when you derefence the pointer as in p[3], the value is the fourth array in the slap of memory. However, this value decays to a pointer to its first element in almost all contexts, so when you say p[3][5] the value is the 6th element within the 4th array within the memory slap.
Sorry, if this sounds a bit confusing, but it's really the same thing that's happening when you declare an array with char array[10][10];, except that the memory comes from a different place.
First things first : do not cast the return value of malloc in C. This is not your code, but anyway, it is always good to say.
Also, the loops should be rewritten like so : for(i = 1; i < 10; i++) or maybe for(i = 0; i < 10; i++). i = i is probably an error (what is that website, again ?), and I will assume so.
char **p;
int i;
p = malloc(10*sizeof(char*));
*p = malloc(10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = p[0] + 10*i;
This first code allocates 10 char* to p, and then 10 char to *p, which is equivalent to p[0]. Then, it puts the addresses of an unallocated 2D array into the other values of p[i] for i from 1 to 9. Since the array is not allocated (or only partially - p[0] is allocated), this is pretty bad.
char **p;
int i;
p = realloc(p, 10*sizeof(char*));
*p = realloc(p, 10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = p[0] + 10*i;
This second code uses realloc instead of malloc, which does not solve the previous problems, but also adds probable segmentation faults : realloc on an uninitialized pointer is a bad idea.
char **p = NULL;
int i;
p = malloc(10*sizeof(char*));
*p = malloc(10*sizeof(char));
for(i = 1; i < 10; i++)
p[i] = realloc(p[i-1], 10*i*sizeof(char));
This third code does the same as the first one for the first part, but then uses realloc on p[i] for i starting with 0. I assume realloc deallocates the pointer you pass to it, so this is not really a good idea. And the 10*i*sizeof(char) is not a good idea either. Basically, you will have p[9] allocated with 90 char, and nothing else. And, by the way, initializing p to NULL here doesn't do anything.
char **p;
int i;
p = malloc(10*sizeof(char*));
for(i = 0; i < 10; i++)
p[i] = malloc(10*sizeof(char));
This fourth code has something good at least : it allocates separately each p[i] for i from 0 to 9 (I assume i starts with 0 here, unlike in the other codes). So, this might be the answer you are looking for.
Finally, the question is badly formulated since none of these codes have the same semantics as a declaration like char p[10][10].
Edit :
If you want a dynamically allocated 2D array, you can use this for instance :
int i;
char **p = malloc(10 * sizeof *p);
for(i = 0; i < 10; i++)
p[i] = malloc(10 * sizeof *p[i]);
You can also, as cmaster did, use a pointer to an array type (like char[10]). This is the exemple from cmaster : char (*p)[10].
Well let's see:
This will likely lead to errors because p[1][0] (among others) points to invalid memory locations.
This is undefined behavior because you pass an uninitialized pointer to realloc().
That code possibly leaves uninitialized pointers all over the place.
This code loops from [1, 10), where I would expect [0, 10). So it's also terrible.
Therefore:
All of these are terrible. The correct code is either:
char (*p)[10] = malloc(10 * sizeof(*p));
Or:
char **p = malloc(10 * sizeof(*p));
for (int i=0; i<10; ++i)
p[i] = malloc(10 * sizeof(**p));
I'm doing a school project and this problem came up.
by the way, i can't use library.
How to convert a int variable to char array?
I have tried this but it didn't work, tried a lot of other things and even magic doesn't work...
char *r = malloc(sizeof(char*));
int i = 1;
r[counter++] = (char) i;
Can someone help me?
Thank you for your time.
In your code, you should allocate for char size and not char *. Please try with this code segment
char *r = malloc(sizeof(char) * N); // Modified here
int i = 1;
r[counter++] = i & 0xff; // To store only the lower 8 bits.
You could also try this:
char *r = malloc(sizeof(char));
char *s = (char*)&i;
r[counter++] = s[0];
This is an other funny way to proceed and it allows you to access the full int with:
s[0], s[1], etc...
Do you mind losing precision? A char is generally 8 bits and an int is generally more. Any int value over 255 is going to be converted to its modulo 255 - unless you want to convert the int into as many chars as is takes to hold an int.
Your title seems ot say that, but none of the answers give so far do.
If so, you need to declare an array of char which is sizeof(int) / sizeof(char) and loop that many times, moving i >> 8 into r[looop_var]. There is no need at all to malloc, unless your teacher told you to do so. In whch case, don't forget to handle malloc failing.
Let's say something like (I am coding this w/o compiling it, so beware)
int numChars = sizeof(int) / sizeof(char);
char charArry[numChard]; // or malloc() later, if you must (& check result)
int convertMe = 0x12345678;
int loopVar;
for (loopVar = 0; loopvar < numChars)
{
charArry[loopVar ] = convertMe ;
convertMe = convertMe >> 8;
}
If you can't use the library, you can't use malloc.
But this will work:
int i = 0;
char *p = (char *)&i;
p[0] = 'H';
p[1] = 'i';
p[2] = '!';
p[3] = '\0';
printf("%s\n", p);
Assuming your int is 32bit or more (and your char is 8).
It then follows that if you have:
int i[100];
You can treat that as an array of char with a size equal to sizeof (i). i.e.
int i[100];
int sz = sizeof(i); // probably 400
char *p = (char *)i; // p[0] to p[sz - 1] is valid.
You can use a union instead. Assuming that sizeof int == 4,
typedef union {
int i;
char[4] cs;
} int_char;
int_char int_char_pun;
int_char_pun.i = 4;
for (int i = 0; i < 4; i++) {
putchar(int_char_pun.cs[i]);
}
Be careful; int_char.cs usually won't be a null-terminated string, or it might be, but with length < 4.
if you don't want to include the math library:
unsigned long pow10(int n);
void main(){
char test[6] = {0};
unsigned int testint = 2410;
char conversion_started = 0;
int i=0,j=0;float k=0;
for(i=sizeof(test);i>-1;i--){
k=testint/pow10(i);
if(k<1 && conversion_started==0) continue;
if(k >= 0 && k < 10){
test[j++]=k+0x30;
testint = testint - (k * pow10(i));
conversion_started=1;
}
}
test[j]=0x00;
printf("%s",test);
}
unsigned long pow10(int n){
long r = 1;
int q = 0;
if(n==0) return 1;
if(n>0){
for(q=0;q<n;q++) r = r * 10;
return r;
}
}
NOTE: I didn't care much about the char array length, so you might better choose it wisely.
hmm... what is wrong with the code below
char *r = malloc(sizeof(char) * ARR_SIZE);
int i = 1;
sprintf(r,"%d",i);
printf("int %d converted int %s",i,r);
will it now work for you
The reason why I am stuck on this is because of how C handles arrays, which is through pointers which I am new at. This is my case(not exactly my problem but a simplistic case):
char *keywords[k_num_of_keywords];
for(int i = 0; i < k_num_of_keywords; i++) {
char temp[] = "float";
keywords[i] = temp;
}
In this case, it would put float in all the indexes, but more importantly, the same address of wherever the string "float" is located. My case is slightly different, because I want to automate initializing a new char array for each index, but still use the same variable, rather than the same address in each index. How can I accomplish this in a for loop?
You should allocate memory for every element for "keywords", for example:
char *keywords[k_num_of_keywords];
for(int i = 0; i < k_num_of_keywords; i++) {
char temp[] = "float";
int len = strlen(temp);
keywords[i] = (char *)malloc(sizeof(char) * (len + 1));
memcpy(keywords[i], temp, len + 1);
}
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?