[C++] Segmentation Fault

Pagina: 1
Acties:
  • 135 views sinds 30-01-2008
  • Reageer

  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
Ik heb het volgende stukje code. Ik krijg op regel 79 een sigmantation fault. Ik snap alleen niet hoe dit nou kan ontstaan. Eerder in de code gebruik ik hem ook al. Wanneer die fout ontstaat draait die in een while loop en in een if statement. Zou dit uit maken?

Wat ik in dit programma doe is een midi poort uitlezen voor input. Als code 74 binnenkomt moet het geluid harder en als code 73 binnen komt het geluid zachter. ./volume is dan het proggie waarmee je het volume harder en zachter kan zetten.

Dit draai ik allemaal onder linux.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <signal.h>
#include "RtMidi.h"
#include <unistd.h>
#define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )

bool done;
static void finish(int ignore){ done = true;}

void usage(void) {
  // Error function in case of incorrect command-line
  // argument specifications.
  std::cout << "\nuseage: remini <port>\n";
  std::cout << "    where port = the device to use (default = 0).\n\n";
  exit(0);
}

int main(int argc, char *argv[])
{
  RtMidiIn *midiin = 0;

  std::vector<unsigned char> message;
  int nBytes;
  double stamp;
  char commando[256];
  int volume;

  // volume op normaal niveau instellen
  volume = 20;
  sprintf(commando, "./volume -r %d -l %d", volume, volume);
  system(commando);

  // Minimal command-line check.
  if ( argc > 2 ) usage();

  // RtMidiIn constructor
  try {
    midiin = new RtMidiIn();
  }
  catch (RtError &error) {
    error.printMessage();
    exit(EXIT_FAILURE);
  }

  // Check available ports vs. specified.
  unsigned int port = 0;
  unsigned int nPorts = midiin->getPortCount();
  if ( argc == 2 ) port = (unsigned int) atoi( argv[1] );
  if ( port >= nPorts ) {
    delete midiin;
    std::cout << "Invalid port specifier!\n";
    usage();
  }

  try {
    midiin->openPort( port );
  }
  catch (RtError &error) {
    error.printMessage();
    delete midiin;
    exit(1);
  }

  // Don't ignore sysex, timing, or active sensing messages.
  midiin->ignoreTypes( false, false, false );

  // Install an interrupt handler function.
  done =false;
  (void) signal(SIGINT, finish);

  // Periodically check input queue.

  while ( !done ) {
    stamp = midiin->getMessage( &message );
    nBytes = message.size();

      if ((int)message[1] == 74 && (int)message[0] == 144 && (volume < 100) && (nBytes > 0)) {
        volume = volume + 5;
        sprintf(commando, "./volume -r %d -l %d", volume, volume);
        system(commando);
      }
      if ((int)message[1] == 73 && (int)message[0] == 144 && (volume > 10) && (nBytes > 0)) {
        volume = volume - 5;
        sprintf(commando, "./volume -r %d -l %d", volume, volume);
        system(commando);
      }

    SLEEP( 10 );
  }

  delete midiin;
  return 0;
}

[ Voor 11% gewijzigd door harmageddon op 25-05-2005 14:16 ]

Aap!


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Welke waarde heeft volume op het moment dat ie eruit klapt? Ik zie je namelijk nergens die message weer clearen, dus ik heb het vermoeden dat hij oneindig loopt. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
De waarde van volume is nog het zelfde als er boven. Want ik heb nog geen input gegeven en hij klapt er al uit.

Message is een queue en die kan 1024 berichten bevatten.

Anyway Ik druk nergens op en doe niks en toch klapt die er uit.

Aap!


  • GX
  • Registratie: Augustus 2000
  • Laatst online: 14-05-2025

GX

Nee.

Ik zie je nergens done op true zetten zodat de loopt er mee ophoudt. Ziet er een beetje uit als een infinite loop.

  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
Er zit een interrupt handler in:
code:
1
2
3
  // Install an interrupt handler function.
  done =false;
  (void) signal(SIGINT, finish);


en boven aan staat
code:
1
static void finish(int ignore){ done = true;}

Aap!


  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
Oke nieuwe ontwikkeling... Hij valt over de volgende code:
code:
1
volume = volume + 5;


Maak ik daar bijv, dan werkt het wel (het heeft alleen niet het gewenste effect)
code:
1
tempje = volume + 5;

Aap!


  • GX
  • Registratie: Augustus 2000
  • Laatst online: 14-05-2025

GX

Nee.

harmageddon schreef op woensdag 25 mei 2005 @ 15:07:
Oke nieuwe ontwikkeling... Hij valt over de volgende code:
code:
1
volume = volume + 5;


Maak ik daar bijv, dan werkt het wel (het heeft alleen niet het gewenste effect)
code:
1
tempje = volume + 5;
volume += 5; ?

  • Semyon
  • Registratie: April 2001
  • Laatst online: 08:48
harmageddon schreef op woensdag 25 mei 2005 @ 15:07:
Oke nieuwe ontwikkeling... Hij valt over de volgende code:
code:
1
volume = volume + 5;
Feit dat hij op deze regel valt zegt helemaal niet dat daar ook de fout zit. Vaak heb je dan ergens van te voren met wat pointers op plaatsen geschreven wat niet de bedoeling was. Je laat het programma dan in min of meer ongedefinieerd status achter en dan kan het crashen op een hele andere regel... Ik heb niet echt naar je code gekeken, maar het klinkt heel erg als je ergens op plekken aan het schrijven bent waar je niet zou moeten.

p.s. het is geen useage maar usage.

Only when it is dark enough, can you see the stars


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 10:04
Probeer eens al je calls naat sprintf te vervangen naar snprintf, waarbij je de maiximale grootte kunt opgeven (256)

Waarschijnlijk zit je ergens buiten je(een) buffer te schrijven. ( Welk hardware platform gebruik je ?)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

(int)message[1] == 74 && (int)message[0] == 144 && (volume < 100) && (nBytes > 0)

dat moet andersom...

(nBytes > 0 ) && (int)message[1] == 74 && (int)message[0] == 144 && (volume < 100)

dus eerst nBytes checken, logisch dat je fouten krijgt :+

Ik zou het btw zo doen:

code:
1
2
3
4
5
6
7
8
if ( nBytes >= 2 && (int)message[0] == 144 ) {
  if ( (int)message[1] == 74 && volume < 100 ) {
    // Volume omhoog
  } else if ( (int)message[1] == 73 && volume > 10 ) {
    // Volume omlaag
  }
  // Haal eerste 2 berichten van queue af... (message.pop ??)
}


En als laatste.. moet je die berichten niet van de queue afhalen na iedere loop ??

[ Voor 60% gewijzigd door c0deaddict op 25-05-2005 16:08 ]


  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
farlane schreef op woensdag 25 mei 2005 @ 16:00:
Waarschijnlijk zit je ergens buiten je(een) buffer te schrijven. ( Welk hardware platform gebruik je ?)
linux slackware

Aap!


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Waarschijnlijk zit je ergens buiten je(een) buffer te schrijven.
Klopt, want message[0] en message[1] bestaan wss nog niet als ze uitgelezen worden.
Dat komt omdat eerst message[0] en message[1] vergeleken worden en dan pas gekeken word of nBytes groter is als 0 (dus of de berichten wel bestaan...)

  • harmageddon
  • Registratie: Januari 2002
  • Laatst online: 08:51
KLEI_j0s je bent geweldig! Het werkt nu!

Thanks!

Aap!


  • c0deaddict
  • Registratie: Mei 2004
  • Laatst online: 10-01 12:11

c0deaddict

Don't be lame, be KLEI

Mooi :D
Graag gedaan :)
Pagina: 1