This line arr = (char*)malloc (2 * sizeof (char)); will allocate memory for 2 bytes only. But you are overwriting the memory by accessing the more 8 or more than 8 byes. If you access more than two byes means, it will give some unpredictable issue. In case you want more memory please follow the below code.
#define USER_SIZE 10
arr = (char*)malloc ( USER_SIZE * sizeof (char));
Assign the value in USER_SIZE macro and then allocate the memory as much as you want.
Example for 2D pointer ( 5 X 10 )
#define ROW 5
#define COLUMN 10
main()
{
unsigned char **p = NULL, colum = 0;
p = malloc ( ROW * sizeof ( unsigned char *) );
for (;colum< ROW; ++colum )
{
p[colum] = malloc (COLUMN * sizeof (unsigned char ));
}
}
Answer from mahendiran.b on Stack OverflowThis line arr = (char*)malloc (2 * sizeof (char)); will allocate memory for 2 bytes only. But you are overwriting the memory by accessing the more 8 or more than 8 byes. If you access more than two byes means, it will give some unpredictable issue. In case you want more memory please follow the below code.
#define USER_SIZE 10
arr = (char*)malloc ( USER_SIZE * sizeof (char));
Assign the value in USER_SIZE macro and then allocate the memory as much as you want.
Example for 2D pointer ( 5 X 10 )
#define ROW 5
#define COLUMN 10
main()
{
unsigned char **p = NULL, colum = 0;
p = malloc ( ROW * sizeof ( unsigned char *) );
for (;colum< ROW; ++colum )
{
p[colum] = malloc (COLUMN * sizeof (unsigned char ));
}
}
What you are doing is called buffer overflow by writing beyond the bounds of memory allocated by malloc call. The compiler doesn't do bounds checking (it assumes you know what you are doing, and you only pay for what you use) and allow you to compile and run. However, it will lead to undefined behaviour and your program may crash. You shouldn't rely on such behaviour.
You, the programmer, has to make sure that you don't do illegal memory access. You should not cast the result of malloc. Also, malloc can fail to allocate memory in which case it returns NULL, the null pointer, which you should take care of. You can combine the two statements into one.
int length = 8; // you can also use a macro
char *arr = malloc(length * sizeof *arr);
if(arr) {
// malloc call successful
// do stuff with arr
}
How do I cin and cout dynamic char arrays in c++? (example names)
c - Dynamic memory allocation for pointer arrays - Stack Overflow
Dynamic char array length - C++ Forum
dynamic allocation for char*
Videos
hey! I am stuck on this question, I have to cin and cout a dynamic array of characters (not using library function/ c++ string types), here are the two issues i am facing:
-
I do not know how long the name would be so should I just take a precondition that it should be smaller than let's say 100? or is there a way that I can create a dynamic array without specifying coloum size?
-
this code that i came up with is producing weird result and i have no clue how to correct it T_T
I would be really thankful if you all can help me with this T_T.
my needed output should look something like:
enter name #1: abc def
enter name #2: ghi jkl...
.
.
.
enter name #n: nnn mmm
int main()
{
int n, j=0;
cout<<"How many names do you want to enter ? ";
cin>>n;
char** name = new char*[n];
for(int i=0; i<n; i++)
{
name[i]=new char[100];
}
for(int i=0; i<n; i++)
{
cout<<"enter name #"<<i+1 <<" :";
do
{
cin>>name[i][j];
j++;
}while(name[i][j]!='\n');
}
for(int i=0; i<n; i++)
{
for(int j=0; name[i][j]!='\n' ; j++)
{
cout<<name[i][j];
}
cout<<endl;
}
}Edit: Thank You so much for helping me with this problem however I figured a way to do it, it's definitely not the best or the most useful but our professor won't vibe with any other straight ways lmao here's what I came up with and the output I get, please let me know what yall think!
int main()
{
int n;
cout<<"How many names do you want to enter ? ";
cin>>n;
char** lastname = new char*[n];
for(int i=0; i<n; i++)
lastname[i]=new char[100];
char ** firstname = new char*[n];
for(int i=0; i<n; i++)
firstname[i]=new char[100];
for(int i=0; i<n; i++)
{
cout<<"enter name #"<<i+1 <<" :";
cin>>firstname[i]>>lastname[i];
}
for(int i=0; i<n; i++)
{
cout<<firstname[i]<<" "<<lastname[i];
cout<<endl;
}
}
/* OUTPUT :
How many names do you want to enter ? 3
enter name #1 :Fucker Certified
enter name #2 :Flex Offender
enter name #3 :Billy Balls
Fucker Certified
Flex Offender
Billy Balls
*/I am pretty sure it's not the most efficient but this was all I could think of T_T
once again Thank You so muchhh!!
In C a string is a char*. A dynamic array of type T is represented as a pointer to T, so for char* that would be char**, not simply a char* the way you declared it.
The compiler, no doubt, has issued some warnings about it. Pay attention to these warnings, very often they help you understand what to do.
Here is how you can start your testing:
char **aPtr;
int len = 1; // Start with 1 string
aPtr = malloc(sizeof(char*) * len); // Do not cast malloc in C
aPtr[0] = "This is a test";
printf("%s",aPtr[0]); // This should work now.
char *str; //single pointer
With this you can store one string.
To store array of strings you Need two dimensional character array
or else array of character pointers or else double pointer
char str[10][50]; //two dimensional character array
If you declare like this you need not allocate memory as this is static declaration
char *str[10]; //array of pointers
Here you need to allocate memory for each pointer
loop through array to allocate memory for each pointer
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
char **str; //double pointer
Here you need to allocate memory for Number of pointers and then allocate memory for each pointer .
str=malloc( sizeof(char *)*10);
And then loop through array allocate memory for each pointer
for(i=0;i<10;i++)
str[i]=malloc(SIZE);
To get some memory to your string, you have to tell malloc how many bytes of memory you want. sizeof(char) returns 1, therefore, you'll only have 1 byte. In C, strings are terminated by the NULL byte (\0), and printf and others will print until they find that NULL terminator.
If you do something like this:
char *str = malloc(1);
*str = 'a';
printf("%s", str);
You will probably get a very strange output, since you have no NULL terminator.
When you use the unsigned x; str = malloc(x);, it's actually undefined how many bytes you have, since that x variable is not initialized.
Since your question is very unclear, what I can tell you (from what I think you're asking) is how to actually get space for a string of 63 characters plus the NULL terminating byte.
char *str = malloc(64);
strcpy(str, "Stack Overflow");
printf("%s", str);
That will do it.
Also note that the memory block returned by malloc will not be zeroed, therefore you can't possibly know what's in it (that could be the reason you're getting garbage when you're printing).
I recommend you read about memory allocation in a good C book or in Wikipedia...
After your edit and "MCVE"
I made some edits to what I think it is you want. The modifications are explained in the comments of the source. Let me know if you have any doubts.
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc, free, realloc */
#include <string.h> /* strcat */
#include <ctype.h> /* isalnum */
#include <conio.h> /* getch */
int main(void)
{
char add[2];
char str2[200];
char c;
int temp = -1;
int num = 0;
char *str3;
/* I just think 'count' is an int, since you didn't put it in the code,
* I also deduced that @count will be used as the length of @str3
*/
int count;
/* Here, count is not initialized, so you MUST initialize it in order
* to call malloc with it! Since it seems you want to add character by
* character using realloc, then we just malloc() 2 bytes - 1 for a
* character and one for the NULL terminator.
*/
count = 2;
str3 = malloc(count);
/* You will be using @strcat to append strings to @str3, so you need
* to put a NULL terminator in it, because strcat will look for that
* NULL byte to find where it should append
*/
*str3 = 0x0;
while((c = getch()) != '\r') {
for (int i = 0;i < 200; i++) {
if (str2[i] =='\0') {
num = i;
break;
}
}
if ((temp == -32) || (temp == 0)) {
/* empty */
} else {
if(isalnum((char)c) == 0)
{
if((c == '\'') || (c == -118) || (c == -115) || (c == -107) || (c == -123) || (c == -105)|| (c == 32))
{
/* this is not the optimal way of using realloc, because
* you should first check for errors, but will do for
* this example.
* You must assign the returned value of realloc to str3.
*
* Also, since @count contains the length
* of @str3, you need to increment it.
*/
str3 = realloc(str3, ++count);
printf("true: %c\n",c);
add[1] = '\0';
add[0] = c;
strcat(str3,add);
strcat(str2,add);
printf("str2: %s\n",str2);
printf("str3: %s\n",str3);
} else if (c == 8) {
printf("Deleting something...\n");
}
} else {
/* see notes above on realloc */
str3 = realloc(str3, ++count);
printf("true: %c\n",c);
add[1] = '\0';
add[0] = c;
strcat(str3,add);
strcat(str2,add);
printf("str2: %s\n",str2);
printf("str3: %s\n",str3);
}
}
printf("ASCII Code: %d\n",c);
temp = c;
}
return 0;
}
In the first two cases, you are only allocating enough space for a single char. If you attempt to write more than one to that block of memory, you'll write past the end of the memory that was allocated for you. Doing so invokes undefined behavior, which in this case manifests as printing strange characters.
In the third case, you allocate x bytes of memory, however x is uninitialized and has an indeterminate value. Reading an indeterminate value is also undefined behavior. In this case it happens to work because the indeterminate value happens to be a valid value and is large enough to hold the string you want, however you can't depend on that behavior.
You need to allocate a byte for every character that you'll need, plus 1 for the terminating null byte that ends a string in C.
This code is surely not what you intended:
char** arguments = (char**)malloc(sizeof(char));
It allocates a block of memory large enough for one char, and sets a variable of type char ** (arguments) to point to it. But even if you wanted only enough space in arguments for a single char *, what you have allocated is not enough (not on any C system you're likely to meet, anyway). It is certainly not long enough for multiple pointers.
Supposing that pointers are indeed wider than single chars on your C system, your program invokes undefined behavior as soon as it dereferences arguments. A segmentation fault is one of the more likely results.
The simplest way forward is probably to scan the input string twice: once to count the number of individual arguments there are, so that you can allocate enough space for the pointers, and again to create the individual argument strings and record pointers to them in your array.
Note, too, that the return value does not carry any accessible information about how much space was allocated, or, therefore, how many argument strings you extracted. The usual approach to this kind of problem is to allocate space for one additional pointer, and to set that last pointer to NULL as a sentinel. This is much akin to, but not the same as, using a null char to mark the end of a C string.
Edited to add:
The allocation you want for arguments is something more like this:
arguments = malloc(sizeof(*arguments) * (argument_count + 1));
That is, allocate space for one more object than there are arguments, with each object the size of the type of thing that arguments is intended to point at. The value of arguments is not accessed by sizeof, so it doesn't matter that it is indeterminate at that point.
Edited to add:
The free() call at the end is also problematic:
free(buffer);
At that point, variable buffer points to the same allocated block as the last element of arguments points to (or is intended to point to). If you free it then all pointers to that memory are invalidated, including the one you are about to return to the caller. You don't need to free buffer at that point any more than you needed to free it after any of the other allocations.
This is probably why you have a segmentation fault:
In char** arguments = (char**)malloc(sizeof(char));, you have used malloc (sizeof (char)), this allocates space for only a single byte (enough space for one char). This is not enough to hold a single char* in arguments.
But even if it was in some system, so arguments[argCount] is only reading allocated memory for argCount = 0. For other values of argCount, the array index is out of bounds - leading to a segmentation fault.
For example, if your input string is something like this - "Hi. How are you doing?", then it has 4 ' ' characters before \n is reached, and the value of argCount will go up till 3.
General malloc
man malloc may be helpful. malloc takes the minimum number of bytes you need of memory (i.e. malloc can choose to provide you more). So if you need exactly 10 elements in your char array, it may be best to simply allocate char* argv[10] as you have already done. However, this creates a container for exactly 10 char* which are not yet defined. Thus, for each char*, argv[0]...argv[9] you can define exactly what goes in there. For instance, if you want to malloc a string of size 200 for argv[0], you would use a statement as follows (notice that 200 can be held in either a constant or a variable):
argv[0] = malloc(200 * sizeof(char));
Generally, sizeof(char) == 1 byte, so this value is probably going to try to get 200 bytes. However, at this point you can modify argv[0] in any way you need to (i.e. strncpy, strncat, etc.).
Now, if you do not know how many arguments you may have, you can allocate your container on the fly. So instead of char* argv[10], you can try to allocate a char** argv. To do this, you would execute the following statement:
int SOME_SIZE = 1500 ; // Or some dynamic value read, etc.
char** argv = malloc(SOME_SIZE * sizeof(char*));
Often times the sizeof(char*) == 4 bytes on a 32-bit system (size of a typical pointer). Now you can use this chunk of memory, argv, in a similar way that has been done before. For ease of thinking about this, using malloc in this way allowed you to perform a relatively equivalent operation of char* argv[WITH_SOME_DYNAMIC_NUMBER]. Thus, you can manipulate this new container in a similar way as I have described above.
Remember though, when you are done with memory created by malloc, you must call free or else it will not be deallocated until the program terminates.
Your Problem
If I understand your question correctly, you have a flattened string which you want to turn into a string array for execve. I will work out a simple example trying to explain one of the many ways this can be done.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void someMethod()
{
char* argv[10];
char* path = getMyPath();
// Notice - this is a little messy and can/should be encapsulated away in another
// method for ease of use - this is to explicitly show, however, how this can work.
argv[9] = malloc((strlen(path) + strlen("--path=") + 1) * sizeof(char));
strncpy(argv[9], "--path=", strlen("--path="));
argv[9][strlen("--path=")] = '\0'; // NULL-terminate since strncpy doesn't
strncat(argv[9], path, strlen(path));
// Do stuff with array
printf("%s\n", argv[9]);
// Technically, you should never get here if execve succeeds since it will blow this
// entire program away (unless you are fork()'ing first)
free(argv[9]);
}
you can malloc the memory that strcat() will use, or you can use a larger-than-needed char buffer[N] on the stack.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char * someFunction();
int main(int argc, char ** argv) {
const char[] path = "commandName";
const char[] arg1 = "--config=moo";
const char[] arg2 = "--console";
const char[] arg3 = "--something=moo2";
//arg4 is skiiped
const char[] arg5 = "--format=x";
const char * mypath = someFunction();
const char[] pathprefix = "--path=";
size_t pathprefixlength = strlen(pathprefix);
size_t stringlength = pathprefixlength + strlen(mypath);
char * arg4 = (char *)malloc(stringlength + 1);
strcpy(arg4, pathprefix);
strcpy(arg4 + pathprefixlength, mypath);
arg4[stringlength] = '\0'; //null terminate
char *argvec[7]; // array of pointers
argvec[0] = path;
argvec[1] = arg1;
argvec[2] = arg2;
argvec[3] = arg3;
argvec[4] = arg4;
argvec[5] = arg;
argvec[6] = NULL;
//do something with argvec;
free(arg4);
}
This:
realloc(input, (sizeof(char)));
is wrong. The realloc() function doesn't modify the given pointer (it can't!), it returns the new pointer. It can also fail, and return NULL.
Also, the second argument doesn't make any sense at all, it should be the new desired total size of the previously allocated buffer, but you're always passing (a very obscure) 1. It's not "grow this by this amount", it's the rather more low-level "attempt to grow this to this new size, and return the new location of the grown buffer".
Please read the documentation very carefully.
realloc(input, (sizeof(char)));
You are reallocating with same size (i.e 1 byte). It shoud be:
while((temp_c = getchar()) != '\n') {
realloc(input, (string_len + 1) * (sizeof(char)));
input[string_len++] = temp_c;
If i have an array already full of data in a function:
char line [10] [128]
how would i dynamically allocate it so that i can use it in other functions?