Casting Double Pointer and How to utilize in C - c

Here is basically a simple code of double pointer and what I am trying to use:
int argsCount = 1;
char **cmdArgs1 = malloc((argsCount + 1)*sizeof(char*));
I want to input values into the cmdArgs1 and here is basically what I am doing and causing seg fault
for(counter = 0; counter < argsCount; counter++)
{
strcpy(cmdArgs1[counter],"ls");
}
I'm thinking that I can't use "cmdArg1[counter]" to copy to "ls" because the double pointer doesn't work that way? I'm not sure...
Even I think it's a bit vague, but I don't know how to phrase the question well, I will try to update based on the comment. Thx!

Your cmdArgs1 is a pointer to a pointer, meaning that it is not enough to allocate space for the array itself. You need to allocate space for the individual arrays of characters (or for the individual C string).
You can do it in a separate call of malloc
for(counter = 0; counter < argsCount; counter++)
{
cmdArgs1[counter] = malloc(strlen("ls")+1); // +1 for null terminator
strcpy(cmdArgs1[counter], "ls");
}
or with strdup:
for(counter = 0; counter < argsCount; counter++)
{
cmdArgs1[counter] = strdup("ls");
}
In both cases your program is liable for freeing the elements of the array before freeing the array itself:
for(counter = 0; counter < argsCount; counter++)
{
free(cmdArgs1[counter]);
}
free(cmdArgs1);

Related

segmentation fault (core dumped) error when trying to copy from an array

trying to copy stuff from b into a but i get that error
someone told me it means i'm trying to access memory that i'm not allowed to, but i don't know what should i do to make it compile.
replace(txt , code);
string replace(string a , string b)
{
string alpha[26] = {"abcdefghijklmnopqurstuvwxyz"};
for (int i = 0; i < strlen(a); i++)
{
for(int n = 0; n < 26; n++)
{
if(a[i] == alpha[n])
{
a[i] = b[n];
i++;
}
}
}
return word;
}
i'm a beginner so no comments about clean coding or syntactic sugar or stuff like that just help me resolve this please
It looks like you have some problems with understending pointers, so I recommend you to read about them. Also consider reading about datatypes and types from STL you are using. (cause std::string is already an array of values so, when you are creating std::string[26], you actually are creating pointer to a pointer)
I guess you have are trying to do something like that:
std::string replace(string a , string b)
{
std::string alpha = {"abcdefghijklmnopqurstuvwxyz"};
for (size_t i = 0; i < a.size(); ++i)
{
for(size_t n = 0; n < alpha.size(); ++n)
{
if(a[i] == alpha[n])
{
a[i] = b[n];
i++; // Also, I think you doesnt need this line, cause you already incrementing i in for loop
}
}
}
return a;
}
Also you have used strlen() on your string, that also is not really correct, cause it is used on char values. If you whant to get length of a string it is better to use string.lenght()
Also, It is better to use size_t or unsigned int instead of int in this case, cause you don't need negative numbers in order to parce these strings. ()

copy two arrays of int to one char* in C

I have to arrays of int for example arr1={0,1,1,0,0}, arr2={1,0,1,1,1} and I need to return 1 char* created by malloc that will be shown like this : "01100,10111".
when I do for loop it doesn't work, how can I do it ?
char* ans = (char*)malloc((size * 2+1) * sizeof(int));
for (int i = 0; i < size; i++)
ans[i] = first[i];
ans[size] = ",";
for (int i = size+1; i < 2*size+1; i++)
ans[i] = second[i];
Among the multitude of problems:
Your allocation size is wrong. It should include space for the separating comma and the terminating nullchar. sizeof(int) is wrong regardless, it should be sizeof(char) and as-such can be omitted (sizeof(char) is always 1).
Your storage is wrong. You want to store characters, and your values should be adjusted relative to '0'.
Your indexing of the second loop is wrong.
In reality, you don't need the second loop in the first place:
char* ans = malloc(size * 2 + 2);
for (int i = 0; i < size; i++)
{
ans[i] = '0' + first[i];
ans[size+1+i] = '0' + second[i];
}
ans[size] = ',';
ans[2*size+1] = 0;
That's it.
1.
char* ans = (char*)malloc((size * 2+1) * sizeof(int));
What is size here? It is not defined and declared in the provided code.
You do not need to cast the return value of malloc() to char. In fact, you do not need to cast the return value of malloc() anymore. It is a habit from the early C days.
Why do you need a char pointer here at all exactly? If you want to print 01100,10111 there is no need to use a char pointer for the output of the integer values.
2.
for (int i = 0; i < size; i++)
ans[i] = first[i];
Again what is size here?
What is first here? If it isn´t a pointer this statement is invalid.
3.
ans[size] = ",";
This operation is invalid. You are trying to assign a string to a pointer.
By the way, I don´t know what you trying to do with this statement. You can incorporate the comma separate in the output of 01100,10111, without your intend to include it int the memory of the int arrays itself.
4.
for (int i = size+1; i < 2*size+1; i++)
ans[i] = second[i];
Same as above: What is value and the type of size?
What is second? If it isn´t it a pointer this statement is invalid.
5.
To answer to the question title:
(How to) Copy two arrays of int to one char* in C
This isn´t possible. You can´t copy two arrays with its data to a pointer to char.
There are at least four issues with your code.
You malloc the wrong size, you want to use sizeof(char).
You need to zero terminate it, so you need to add extra room for the terminating zero
char* ans = (char*)malloc((size * 2+2) * sizeof(char));
second[size * 2+1] = 0;
Also the indexing of the second loop is wrong. You are accessing second array out of bounds. Make the loop more like the first.
We also need to convert the integer value to a char in the loops.
for (int i = 0; i < size; i++)
ans[size+i+1] = second[i] + '0';

Remove some elements from array and re-size array in C

Regards
I want to remove some elements from my array and re-size it.
for example my array is:
char get_res[6] = {0x32,0x32,0x34,0x16,0x00,0x00};
Now I want to remove elements after 0x16, so my desire array is:
get_res[] = {0x32,0x32,0x34,0x16};
what is solution?
You cannot resize arrays in C (unlike Python, for example). For real resizing, at least from an API user's point of view, use malloc, calloc, realloc, and free (realloc specifically).
Anyway, "resizing" an array can be imitated using
a delimiter; for example, a delimiter like 0xff could mark the end of the valid data in the array
Example:
#define DELIMITER 0xff
print_data(char* data) {
for (size_t i = 0; data[i] != DELIMITER; ++i)
printf("%x", data[i]);
}
a member counter; count the number of valid data from the beginning of the array onward
Example:
size_t counter = 5;
print_data(char* data) {
for (size_t i = 0; i < counter; ++i)
printf("%x", data[i]);
}
Notes:
Use unsigned char for binary data. char may be aliasing signed char, which you might run into problems with because signed char contains a sign bit.
There is no need to "remove" them. Just don't access them. Pretend like they don't exist. Same like in stacks, when you "pop" a value from the top of the stack, you just decrement the stack pointer.
Manipulating arrays in C isn't easy as it is for vector in C++ or List in Java. There is no "remove element" in C. I mean that you have to do the job yourself, that is, create another array, copy only the elements you want to this new array, and free the memory occupied by the previous one.
Can you do that? Do you want the code?
EDIT:
Try that. It's just a simple program that simulates the situation. Now, you have to see the example and adapt it to your code.
#include <stdio.h>
#include <stdlib.h>
int main() {
char get_res[6] = {0x32,0x32,0x34,0x16,0x00,0x00};
char target = 0x16;
int pos, i, length = 6; // or specify some way to get this number
for(i = 0; i < length; i++)
if(get_res[i] == target) {
pos = i;
break;
}
pos = pos + 1; // as you have to ignore the target itself
char *new_arr = malloc(pos);
for(i = 0; i < length; i++) {
new_arr[i] = get_res[i];
i++;
}
for(i = 0; i < pos; i++)
printf("%c ", new_arr[i]);
return 0;
}

Dynamically allocating a 2D array in C

I've been reading around and I've been applying what I've been reading to my code but I am not sure if I am missing something.. the 2d array is suppose to mirror sudoku.
I know the problem area is in my arrayMake function.
My professor recommended using a cast with the malloc call so:
sudoku = (int**)malloc(sudokus*sizeof(int*)); but that did not work for me.
int main(){
int sudokus;
int** sudoku;
sudokus = getUserInfo();
sudoku = arrayMake(sudokus);
/*for (int i = 0; i < (SIZE*sudokus), i++;){
for (int j = 0; j < SIZE, j++;){
printf("Numbers[%d][%d]:%d", i, j, sudoku[i][j]);
}
}*/
system("pause");
return 0;
}
int getUserInfo(){
int sudokus;
printf("How many Sudokus are you checking today?\n");
scanf("%d{^\n]\n", &sudokus);
return sudokus;
}
int** arrayMake(int sudokus){
int **sudoku;
int realsize;
realsize = 9 * sudokus;
sudoku = malloc(realsize*sizeof(int*));
if (sudoku == NULL){
printf("Memory allocation failed");
return 0;
}
for (int i = 0; i < realsize, i++;){
sudoku[i] = malloc(9 * sizeof(int));
if (sudoku[i] == NULL){
printf("Memory allocaiton failed");
return 0;
}
}
return sudoku;
}
My professor recommended using a cast with the malloc call so: sudoku = (int**)malloc(sudokus * sizeof(int*)); but that did not work for me.
To dynamically allocate for 2D array, you usually need to do two steps. Your code is not clear as you include a realsize = 9 * sudokus which doesn't make sense. Anyway, for simplicity, lets assume your sudoku is a 3x3 matrix. You'll need to:
Allocate for the pointer to pointer to int:
int **sudoku = malloc( 3 * sizeof( int * ) );
Allocate for each of the individual pointer to int:
for( int i = 0; i < 3; i++ )
sudoku[i] = malloc( 3 * sizeof( int ) );
From what I see your problem exists in your for loops where you have:
for (i = 0;i < realsize , i++)
when you really meant:
for (i = 0;i < realsize ; i++)
^
Note the change of , to ;
scanf("%d{^\n]\n", &sudokus); is a mistake.
I guess you meant the { to actually be a [ but the format string is still wrong even after that change. I think you intended to consume the rest of the input, up to and including a newline character. However, your format string does not actually do that.
Scanf'ing for \n actually means consume any amount of whitespace, so in fact this code (with the [ fix) would continue waiting for input until there was a newline, and also another non-whitespace character typed after the newline.
Better would be:
scanf("%d", &sudokus);
int ch;
while ( (ch = getchar()) != '\n' && ch != EOF ) { }
There are a few different ways to achieve the same goal. (Note that scanning for %d[^\n]%c is not one of them; that string is also broken).
Also I would suggest a different variable name than sudokus. It's confusing having two similarly-named variables sudoku and sudokus. Name it something that reflects its meaning.
For allocating your array, it would be much simpler to take out the arrayMake function and write something like:
int sudoku[9][9];
(I couldn't figure out what sudokus was supposed to mean or what realsize was going to be, but you could put your intended dimension inside the square brackets there).

How would you add chars to an array dynamically? Without the array being predefined?

If I want to add chars to char array, I must do it like this:
#include <stdio.h>
int main() {
int i;
char characters[7] = "0000000";
for (i = 0; i < 7; i++) {
characters[i] = (char)('a' + i);
if (i > 2) {
break;
}
}
for (i = 0; i < 7; i++) {
printf("%c\n", characters[i]);
}
return 0;
}
To prevent from printing any weird characters, I must initialize the array, but it isn't flexible. How can I add characters to a char array dynamically? Just like you would in Python:
characters = []
characters.append(1)
...
There is no non-ugly solution for pure C.
#include <stdio.h>
int main() {
int i;
size_t space = 1; // initial room for string
char* characters = malloc(space); // allocate
for (i = 0; i < 7; i++) {
characters[i] = (char)('a' + i);
space++; // increment needed space by 1
characters = realloc(characters, space); // allocate new space
if (i > 2) {
break;
}
}
for (i = 0; i < 7; i++) {
printf("%c\n", characters[i]);
}
return 0;
}
In practice you want to avoid the use of realloc and of course allocate the memory in bigger chunks than just one byte, maybe even at an exponetial rate. But in essence thats what happening under the hood of std::string and the like: You need a counter, which counts the current size, a variable of the current maximum size (Here it is always current size+1, for simplicity) and some reallocation if the need for space surpasses the maximum current size.
Yes, of course you can add characters dynamically:
quote char[100] = "The course of true love";
strcat( quote, " never did run smooth.";
but only if there is enough room in quote[ ] to hold the appended characters. Or maybe you are asking why, in C, you have to pre-arrange enough character storage whereas, in Python, storage is allocated dynamically. That's how the language was designed in 197x.
C99 does allow dynamically-allocated storage: storage allocated by the system at run time. And a very bad mistake it is, imo.
You cannot unless you use Linked Lists or some other custom data structure.

Resources