Hello!

I am having issues with a project for my C class. We were provided the program shell (structs and the function calls) and we fill in the code for the functions. I did this, however I get a segmentation fault every time I first access my structures. Can anyone give me some help in this area? My first thoughts are that the

SCORE score;

declaration isn't declared as an array, however this is part of the shell that was provided and we're required to not alter the original shell! The function calls/parameters were also provided as part of the shell. Please excuse the ridiculously long code, this is how he wanted it believe it or not! It's supposed to be a <i>really</i> basic "music editor".

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Data Definitions */

typedef struct { //define a data type for NOTE
	int name;
	int pitch;
	int loudness;
	int duration;
} NOTE;

typedef struct { //define a data type for SCORE
	NOTE *thescore;
} SCORE;

void create(SCORE *score, int scoresize) {
	int i, n = 1, p = 1, d = 1, l = 0;

	for (i = 0; i < scoresize; i++) {
		score[i].thescore ->name = n;      //<-- gdb shows segfault HERE
		score[i].thescore ->pitch = p;
		score[i].thescore ->duration = d;
		score[i].thescore ->loudness = l;
		n++;

		if (n == 13) {
			n = 1;
			p++;
		}
		if (p == 8)
			p = 1;
	}
} //create procedure,including any local variables

void show(SCORE *score, int scoresize) {
	int i;
	printf("\nSize: %d\n", scoresize);
	for (i = 0; i < scoresize; i++) {
		printf("\n\tNote:\t%d\tPitch:\t%d\tDuration:\t%d\tLoudness:\t%d\n",
				score[i].thescore->name, score[i].thescore->pitch,
				score[i].thescore->duration, score[i].thescore->loudness);
	}
} //show method

void transposeOctaveUp(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->pitch += 1;
		if (score[i].thescore->pitch == 8)
			score[i].thescore->pitch = 1;
	}
} //Transpose Octave Up procedure,including any local variables

void transposeOctaveDown(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->pitch -= 1;
		if (score[i].thescore->pitch == 0)
			score[i].thescore->pitch = 7;
	}
} //Transpose Octave Down procedure,including any local variables

void doubleTheDuration(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->duration -= 1;
		if (score[i].thescore->duration <= 0)
			score[i].thescore->duration = 1;
	}
} //Double the Duration procedure,including any local variables

void halveTheDuration(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->duration += 1;
		if (score[i].thescore->duration >= 8)
			score[i].thescore->duration = 7;
	}
} //Halve the Duration procedure,including any local variables

void increaseTheLoudness(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->loudness *= 2;
		if (score[i].thescore->loudness == 0)
			score[i].thescore->loudness = 1;
		else if (score[i].thescore->loudness >= 33)
			score[i].thescore->loudness = 32;
	}
} //Increase the Loudness procedure,including any local variables

void decreaseTheLoudness(SCORE *score, int scoresize) {
	int i;
	for (i = 0; i < scoresize; i++) {
		score[i].thescore->loudness /= 2;
		if (score[i].thescore->loudness <= 0)
			score[i].thescore->loudness = 0;
	}
} //Decrease the Loudness procedure,including any local variables

void reverseInOctave(SCORE *score, int scoresize) {
	int i, temp;
	for (i = 0; i < scoresize; i++) {
		temp = ~score[i].thescore->name;
		temp += 14;
		score[i].thescore->name = temp;
	}
} //Reverse in Octave procedure,including any local variables

void reversePitchDuration(SCORE *score, int scoresize) {
	int i, temp;
	for (i = 0; i < scoresize; i++) {
		temp = score[i].thescore->pitch;
		score[i].thescore->pitch = score[i].thescore->duration;
		score[i].thescore->duration = temp;
	}
} //ReversePitchDuration procedure,including any local variables

int main(void) //main procedure
{
	int scoresize = 0; // user provided Score Size;
	// obtain and validate Score size from user placing it's value
	// in the local variable 'scoresize'

	printf("Please enter score size: ");
	scanf("%d[1-1000]", &scoresize);

	SCORE score; // the score
	score.thescore = malloc(scoresize * sizeof(NOTE));
	if (score.thescore == NULL) {
		printf(
				"\nError: Attempt to allocate memory for the array has failed.\n");
		return -1;
	}

	create(&score, scoresize); //call 'create' to initialize score array based on value in 'scoresize'

	show(&score, scoresize); // call 'show'

	transposeOctaveUp(&score, scoresize); //call 'transposeOctaveUp'
	
	doubleTheDuration(&score, scoresize); //call 'doubleTheDuration'

	increaseTheLoudness(&score, scoresize); //call 'increaseTheLoudness'

	reverseInOctave(&score, scoresize); //call 'reverseInOctave'

	reversePitchDuration(&score, scoresize); //call 'reversePitchDuration'

	show(&score, scoresize); //call 'show'

	transposeOctaveDown(&score, scoresize); //call 'transposeOctaveDown'

	halveTheDuration(&score, scoresize); //call 'halveTheDuration'

	decreaseTheLoudness(&score, scoresize); //call 'decreaseTheLoudness'

	reverseInOctave(&score, scoresize); //call reverseInOctave

	reversePitchDuration(&score, scoresize); //call reversePitchDuration

	show(&score, scoresize); //call show

	free(score.thescore); //deallocate space

	return EXIT_SUCCESS;
}

>score.thescore ->name = n;
Close. thescore is your dynamic array, not score :

score->thescore[i].name = n;

Apply that logic to your whole program.

Perfect! That did the trick (big surprise), and it now runs perfectly. Thanks so much.

Thanks, this was really useful and nice example of dynamic memory allocation for nested struct. Thanks again.

This question has already been answered. Start a new discussion instead.