0

I have the following code, it searches for some matches with regex (pcre) then adds the matches to a dynamically growing array (so I can make the matches unique)... the problem I get two warnings when compiling and when running the program crashes.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pcre.h>

int main() {
  pcre *myregexp;
  const char *error;
  int erroroffset;
  int offsetcount;
  int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
  const char *result;
  int n;
  int count = 1;
  char **matches;
  char **more_matches;
  char *subject = "9,5,3,2,5,6,3,2,5,6,3,2,2,2,5,0,5,5,6,6,1,";
  myregexp = pcre_compile("\\d,", PCRE_MULTILINE|PCRE_DOTALL, &error, &erroroffset, NULL);

  if (myregexp != NULL) {
    offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3);

    while (offsetcount > 0) {

      if (pcre_get_substring(subject, offsets, offsetcount, 0, &result) >= 0) {
        printf("%s\n", result);
        more_matches = (char *) realloc(matches, count * sizeof(char));
        if (more_matches!=NULL) {
          matches=more_matches;
          matches[count-1]=result;
          count++;
        }
        else {
          free(matches);
          puts("Error (re)allocating memory");
          exit(1);
       }
      }

      offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), offsets[1], 0, offsets, (0+1)*3);
    }
    for (n=0; n<count; n++) printf("%s\n", matches[n]);
    free(matches);
  } else {
      printf("Syntax error in REGEX at erroroffset\n");
  }

}

casting something wrong?

$ gcc -o pcre_ex_arr pcre_ex_arr.c -lpcre
pcre_ex_arr.c: In function 'main':
pcre_ex_arr.c:29: warning: assignment from incompatible pointer type
pcre_ex_arr.c:32: warning: assignment discards qualifiers from pointer target type
$ ./pcre_ex_arr
2,
*** glibc detected *** ./pcre_ex_arr: realloc(): invalid pointer: 0xb7fcfb80 ***
======= Backtrace: =========
4
  • For one thing, this: sizeof(char) in your realloc should be sizeof(char*), and the types aren't comparable (assigning a const char* to a char*), but thats a different issue. (i.e. matches is the wrong type). You also never initialize matches to NULL before starting this thing up, which is critical for the first iteration to work. Commented Feb 8, 2014 at 20:08
  • Yes, my bad. Let me retry. Commented Feb 8, 2014 at 20:11
  • char **matches = NULL; and char **more_matches = NULL; now the code works, but I get the same warnings when finishing it segfaults. And by the way, printf outputs data twice. Commented Feb 8, 2014 at 20:13
  • sorry, deleted your last post, oops. Commented Feb 8, 2014 at 20:13

1 Answer 1

1

A number of things wrong:

  1. Using the wrong sizeof() when resizing your matches pointer array
  2. Failing to initialize matches to NULL before the parsing begins.
  3. Using the wrong type for the matches and more_matches pointers.
  4. Using a volatile pointer to read-only memory for subject
  5. Casting malloc and realloc is never good in C
  6. The math on your count is flaky-at-best. It should start at 0, not 1

See below:

int main()
{
    pcre *myregexp;
    const char *error;
    int erroroffset;
    int offsetcount;
    int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
    const char *result;
    int n;
    int count = 0;
    const char **matches = NULL;
    const char **more_matches;

    char subject[] = "9,5,3,2,5,6,3,2,5,6,3,2,2,2,5,0,5,5,6,6,1,";
    myregexp = pcre_compile("\\d,", PCRE_MULTILINE|PCRE_DOTALL, &error, &erroroffset, NULL);

    if (myregexp != NULL) {
        offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3);

        while (offsetcount > 0) {

            if (pcre_get_substring(subject, offsets, offsetcount, 0, &result) >= 0)
            {
                printf("%s\n", result);
                more_matches = realloc(matches, (count+1)* sizeof(*more_matches));
                if (more_matches!=NULL)
                {
                    matches=more_matches;
                    matches[count++]=result;
                }
                else
                {
                    free(matches);
                    puts("Error (re)allocating memory");
                    exit(1);
                }
            }

            offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), offsets[1], 0, offsets, (0+1)*3);
        }

        for (n=0; n<count; n++) printf("%s\n", matches[n]);
        free(matches);

    } else {
        printf("Syntax error in REGEX at erroroffset\n");
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.