Reputation: 1208
I wrote three ways of passing arguments to a function that accepts argv argument.
error: conversion
from string literal to 'char *' is deprecated
[-Werror,-Wc++11-compat-deprecated-writable-strings]
The method using malloc works, though it's a tad bit longer.
The last method causes a seg fault. Can you help me figure out the mistake in the third method, where I create an array with predefined size and copy the contents? Why does it fail?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEST3
int console_tester(int argc, char *argv[])
{
printf("argv: %s\n", argv[0]);
return 0;
}
int main()
{
#ifdef TEST1
// works, shortest, but gives compilation warnings
char *test_cmd[2] = {"hello1", "hello2"};
int result = console_tester(2, (char**)test_cmd);
#endif
// works, verbose
#ifdef TEST2
char *test_cmd[2];
test_cmd[0] = malloc(10);
test_cmd[1] = malloc(10);
memset(test_cmd[0], 0, 10);
memset(test_cmd[0], 1, 10);
memcpy(test_cmd[0], "hello1", sizeof("hello1"));
memcpy(test_cmd[1], "hello2", sizeof("hello2"));
int result = console_tester(2, (char**)test_cmd);
free(test_cmd[0]);
free(test_cmd[1]);
#endif
// crash and burn
#ifdef TEST3
char test_cmd[2][10];
memset(&test_cmd[0], 0, 10);
memset(&test_cmd[1], 0, 10);
memcpy(&test_cmd[0], "hello1", sizeof("hello1"));
memcpy(&test_cmd[1], "hello2", sizeof("hello2"));
int result = console_tester(2, (char**)test_cmd);
#endif
return 0;
}
Upvotes: 2
Views: 53
Reputation: 211610
In the third example you're doing an invalid conversion:
char test_cmd[2][10];
memset(&test_cmd[0], 0, 10);
memset(&test_cmd[1], 0, 10);
memcpy(&test_cmd[0], "hello1", sizeof("hello1"));
memcpy(&test_cmd[1], "hello2", sizeof("hello2"));
int result = console_tester(2, (char**)test_cmd);
This produces a compiler warning for me when I strip off the (char**)
brute-force casting:
warning: incompatible pointer types passing 'char (*)[10]' to parameter of type 'char **' [-Wincompatible-pointer-types]
Which really should be an error. You can't switch those arbitrarily. You don't have the right kind of structure to pass in, so you must convert it to the correct structure first.
The other two examples both use char**
properly so they're fine.
This is why turning on all warnings your compiler has to offer can help narrow down problems quickly. C, and by extension C++, really does not care if you're asking to do something invalid, it'll do it if told to do it, and then crash or act really strange because of it.
Upvotes: 1