I need to change params char array in parser function, but after leaving parser function params array is still NULL and it ends with "Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#define SSH_BIN_PATH "\usr\bin\ssh"
void parser(char *route[4], char **params);
int main(int argc, char *argv[]) {
char *route[4];
char **params = NULL;
parser(route, params);
for(int i = 0; i < 4; i++) {
printf("\nRoute: %s\n", params[i]);
}
return 0;
}
void parser(char *route[4], char **params) {
char *userAndPass = NULL;
char *token = NULL;
int line_count = 0;
char lines[100][100];
FILE *file = fopen("/home/user/Documents/format.txt", "r");
if (file == NULL) {
printf("Opening failure.\n");
exit(EXIT_FAILURE);
}
while (fgets(lines[line_count], sizeof(lines[line_count]), file)) {
size_t length = strlen(lines[line_count]);
if (lines[line_count][length - 1] == '\n') {
lines[line_count][length - 1] = '\0';
}
line_count++;
}
fclose(file);
if (strcmp(lines[line_count - 1], "exit") != 0) {
strcpy(lines[line_count], "exit");
line_count++;
}
params = (char**)malloc(line_count * sizeof(char*));
if (params == NULL) {
printf("Memory error.\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < line_count; i++) {
params[i] = strdup(lines[i]);
if (params[i] == NULL) {
printf("Memory error.\n");
exit(EXIT_FAILURE);
}
}
token = strtok(params[0], "@");
if (token != NULL) {
userAndPass = token;
token = strtok(NULL, ":");
if (token != NULL) {
route[2] = token;
token = strtok(NULL, "@");
if (token != NULL) {
route[3] = token;
}
}
}
token = strdup(userAndPass);
token = strtok(token, ":");
if (token != NULL) {
route[0] = token;
if (strlen(userAndPass) != strlen(route[0])) {
token = strtok(NULL, "@");
if (token != NULL)
route[1] = token;
}
else
route[1] = "";
}
}
I can't understand what's a problem, so i even try to do it with 3 pointers like this
void parser(char *route[4], char ***params){
*params = (char**)malloc(line_count * sizeof(char*));
if (*params == NULL) {
printf("Memory error.\n");
exit(EXIT_FAILURE);
}
for (int i = 0; i < line_count; i++) {
*params[i] = strdup(lines[i]);
if (*params[i] == NULL) {
printf("Memory error\n");
exit(EXIT_FAILURE);
}
}
}
int main(){
parser(route, ¶ms);
}
But it didn't help
From the question it seems that you are aware that params
must by passed as a pointer. In other words, that you first code example is wrong because it passes params
by value.
You second example is correct with respect to the way params
is being passed, i.e. pass a pointer to params
instead of passing the value of params
.
However, the second example has another serious problem related to C operator precedence
.
Look at this code:
*params[i] = strdup(lines[i]);
What is it really doing?
It is like a) (*params)[i] = strdup(lines[i]);
or like b) *(params[i]) = strdup(lines[i]);
That makes a hugh difference....
The answer is that it is like b) but you actually want it to be a).
So you need to explicit add the parenthesis and use (*params)[i] = strdup(lines[i]);