Search code examples
cc-stringstrimoperator-precedencepointer-to-pointer

Runtime error: `load of null pointer of type 'char'` when indexing an array


I'm trying to write a trim function, but when I try to use it the compiler is giving me a runtime error or load of null pointer of type 'char' when I try to run this code:

// Trim trailing whitespace
int len = strlen(*str);
int trimmed = 0;

while (isspace(*str[len - 1])) {
    --len;
    trimmed = 1;
}

Here is my compiler command: gcc ./main.c ./json.c -g -m64 -Wall -Wextra -fsanitize=address,undefined,leak -I ./lib/include -L ./lib -o ./json

This is the function that is causing the error:

void _JSON_Trim(char **str) {
  // Trim leading whitespace
  while (isspace(**str) || **str == '\0') {
    ++*str;
  }

  // Trim trailing whitespace
  int len = strlen(*str);
  int trimmed = 0;

  while (isspace(*str[len - 1])) {
    --len;
    trimmed = 1;
  }

  if (trimmed) {
    *str[len] = '\0';
  }
}

This code was semi-working until I added the double pointer symbol (char **str was char *str). However, char *str wasn't properly incrementing the pointer.

Note: the error specifically occurs in the line 11 where while (isspace(*str[len - 1])) { is called. I don't know where in the line it occurs as the compiler doesn't specify.

This is the string that the function is called on:

[
    "HI",
    "Bye"
]

Note: yes I know there's technically nothing to trim here, so the function wouldn't do anything, but it's there incase it does


Solution

  • The postfix subscript operator has a higher priority than the unary dereferncing operator. This line

    while (isspace(*str[len - 1])) {
    

    is equivalent to

    while (isspace(*( str[len - 1] ))) {
    

    while you need to write

    while (isspace( ( *str )[len - 1])) {
    

    And it ie even better to write

    while (isspace( ( unsigned char )( *str )[len - 1])) {
    

    Pay attention to that the variable len shall have type size_t instead of the type int

    int len = strlen(*str);.
    

    size_t is the return type of the function strlen.