UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C
  • » Help: realloc invalid next size / segmentation fault

#1 2009-08-09 03:37 PM

incubis
Member
Registered: 2009-08-09
Posts: 2

Re: Help: realloc invalid next size / segmentation fault

I am currently working to create a piece of code that is able to provide all permutations of a given argument.  In the stripped down code provided below, the function processArgs() is meant to take a constant 1D char array and a 2D char array which will be used to hold the results of the function.

The realloc in the functions only for loop seems to be acting fine and performs several iterations without issue however after the 4th iteration control returns to console and I'm provided with the error "invalid next size: 0x085af008" from glibc, suggesting a segmentation fault.  I've done a fair bit of debugging for this code, stripping it down to it's current version and even rewriting it.  Compiles with no errors or warnings.  Can't seem to find the fault... Any help would be gratefully appreciated.

Note that if i modify the realloc command such that the size_t value is multiplied by an integer, eg. *10, the number of iterations before crash increases in a scalar manner...  Also, the current basic design (eg. usage of iterative realloc rather than single malloc) is required once this skeleton code is fleshed out once again.

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int nPerms(int nLetters);
char* permute(int seed,const char* origString);
int processArgs(const char* charArray, char** storage);

int nPerms(int nLetters) {
	int nPerm = 1; //Product starting value
	
	for (int i=0; i<nLetters; i++) {
		nPerm *= (nLetters-i);
	}
	
	printf("The maximum number of permutations is: %d\n", nPerm);

	return nPerm;
}

char* permute(int seed,const char* origString) {
	// Note: This fn returns an allocated pointer.
	// DANGEROUS USAGE: permute();
	
	char* tmpString = malloc( (strlen(origString)+1)*sizeof(char) );
	
	tmpString[strlen(origString)] = '\0';
	
	if (!tmpString) {
		fprintf(stderr, "char* tmpString failed to initialise.\n");
		exit(EXIT_FAILURE);
	}

	for (int i=1, tmpValue; i<=strlen(origString); i++) {
		tmpValue = tmpString[seed%i];
		tmpString[seed%i] = tmpString[i-1];
		tmpString[i-1] = tmpValue;
		seed /= i;
	}

	return tmpString;
}

int processArgs(const char* charArray, char** storage) {
	int storIndex = 0;
	char* tmpStorage = NULL;
	int maxSeed = nPerms(9);

	
	for (int i=0; i<=maxSeed; i++) {
		tmpStorage = permute(i, charArray);

		storage = realloc(storage, sizeof(storage)+sizeof(char*));

		if (!storage) {
		fprintf(stderr, "char** storage failed to reallocate.\n");
		exit(EXIT_FAILURE);
		}
		
		storage[storIndex] = tmpStorage;
		storIndex++;
		printf("storIndex = %d\n", storIndex);

		tmpStorage = NULL;
	}

	return storIndex;
}
	

int main(int argc, char** argv) {
	if((argc!=2)||(!isalpha(argv[1][0]))) {
		fprintf(stderr, "USAGE: permute [9 lowercase letters]\n");
		exit(EXIT_FAILURE);
	}
	else {
		char charArray[9];

		for (int i=0; i<9; i++) {
			charArray[i] = argv[1][i];
		}
		
		char** storage = malloc(1);
		
		if (!storage) {
			fprintf(stderr, "char** storage failed to initialise.\n");
			exit(EXIT_FAILURE);
		}

		int storIndex = processArgs(charArray, storage);

		for (int i=0; i<storIndex; i++) {
			printf("Value stored at storIndex %d is: %s", storIndex, storage[i]);
		}

		printf("Complete...\n");

		exit(EXIT_SUCCESS);
		
		return 0;
	}
}

Cheers,
Mike.

Offline

#2 2009-08-09 03:49 PM

i3839
Oddministrator
From: Amsterdam
Registered: 2003-06-07
Posts: 2,239

Re: Help: realloc invalid next size / segmentation fault

sizeof(storage) is always the size of a pointer, because that is was 'storage' is.

Offline

#3 2009-08-09 04:50 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,839
Website

Re: Help: realloc invalid next size / segmentation fault

Yeah, i3839 nailed it...  You can only use sizeof() on static/automatic arrays, not passed
in pointers to them...  (Well, you can USE it, obviously, but it won't give you the full size
of the array; only of the pointer...)

What you need to do is pass in another parameter that's a pointer to the current array
size, and increase that when doing the realloc()...

Also, you really need to pass a pointer to "storage" as well, and update that with the
result of the realloc(), since you reference "storage" afterwards in your main()...
Because, realloc() can very well return a completely different pointer value than the
original...  And, with your current design, the only one that knows about that new
pointer value is processArgs(), but main() will still have the old pointer value...

Also, we've said it a million times here, but I'll say it again: for any seg-fault or memory
problems like this, you should run your app through valgrind...  It's really amazingly
great at tracking down stuff like this...

Offline

#4 2009-08-09 06:08 PM

incubis
Member
Registered: 2009-08-09
Posts: 2

Re: Help: realloc invalid next size / segmentation fault

Thanks to both of you, the fix worked perfectly.  Additional +1 to RobSeace, I didn't even think about the fact that my passed storage address ended up being garbage.

Cheers again,
Mike.

Offline

#5 2009-08-15 03:16 PM

0788629219
Guest

Re: Help: realloc invalid next size / segmentation fault

  • Index
  • » C
  • » Help: realloc invalid next size / segmentation fault

Board footer

Powered by FluxBB