简体   繁体   中英

printf char array segment fault C

So I have written a code that sorts words in the right order. The words are being stored via pointers and I have initialized another char array in the program to store the char* argv .

The last for loop is what prints segment fault and I can't figure out why.

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]) {
  int i, j;
  char *key;
  char a[argc-1];
  for(i=1; i < argc; i++){
    a[i-1]= tolower(argv[i]);
      }

  for (i = 2; i < argc; i++) {
    key = argv[i];

    j = i-1;
    while (j >= 1 && strcmp(argv[j], key) > 0) {
      argv[j+1] = argv[j];
      j--;
    }

    argv[j+1] = key;
  }

  for(i = 1; i < argc; i++){
    a[i-1] = *argv[i];
  }

  for (i = 1; i < argc ; i++){
    puts(argv[i]);
  }

  for(i = 0; i < argc-1; i++){
    printf("%s", a[i]);
}
  return 0;
}

input

./a.out orange banana apple

output

apple
banana
orange
Segmentation fault

There are multiple problems in your code

  1. The line a[i - 1] = tolower(argv[i]) is wrong because tolower() takes int as paramater and you are passing char * so it's converting a pointer to int which is legal in c but does not guarantee defined behavior.

  2. You are not setting the '\\0' terminator on the a array which is another cause for problems, specifically when you try to use it as a string, a char array is not a string unless, it's a sequence of printable bytes with a terminating '\\0' byte.

  3. Allocating argc - 1 is not going to work because

    • The value of argc is the number of passed parameters to the executable.
    • If it was the length of the corresponding argv as found by strlen() you would need 1 more byte not less, so it would be argc + 1 in any case.

Why are you using %s

for(i = 0; i < argc-1; i++){
printf("%s", a[i]);

try %c

Your compiler should also give you a warnging on:

printf("%s", a[i]);

warning: format specifies type 'char *' but the argument has type 'char' [-Wformat]

If you change that to a %c it works fine .

As the warning says, when you use it %s printf is expecting a string or a char* and will treat it as such. a[i] is an integer type that can reference an invalid location in memory. So the correct way to do it would be to either use %c, and print a character; or use %s and pass a char* as the second argument.

Or perchance you want args in a. Change the delcaration.

char *a[argc-1];

Then change the assignment.

a[i-1] = argv[i];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM