0

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;
}
3
Contributors
3
Replies
5
Views
6 Years
Discussion Span
Last Post by blech
0

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

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

Apply that logic to your whole program.

0

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

0

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.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.