0

I am currently getting a segmentation fault (Segmentation fault: 11), when I call newUnitID().

No idea what I am doing wrong.

This is my header file where the function is:

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#ifndef UnitManager
#define UnitManager
using namespace std;

char randomIDChar(){
    static const char alphanum[] =
        "0123456789"
        "!@#$%^&*"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    int stringLength = sizeof(alphanum) - 1;
    srand(time(0));
    for(int z=0; z < 21; z++)
    {
        return alphanum[rand() % stringLength];
    }
    return 1;
}

string newUnitID(){
    vector<char> v;
    for(int i=0; i < 50; i++){
        v[i] = randomIDChar();
    }
    string str(v.begin(),v.end());
    return str;
}

#endif
tshepang
  • 12,111
  • 21
  • 91
  • 136
N00byEdge
  • 1,106
  • 7
  • 18
  • simonc's answer is good, but may I suggest that you learn to work with a tool such as Valgrind or GDB? The basics are quite easy to pick up (and that's all you need, really), and it can save you a lot of time in trying to find bugs like these in your code. – Anonymous Nov 01 '13 at 23:20

2 Answers2

6

vector's operator [] access existing elements; it doesn't create new elements. You start with an empty vector so

v[i] = randomIDChar();

access beyond the vector's end. You could change this to

v.push_back(randomIDChar());

Note that there is also a problem with randomIDChar. You should only seed the random number generator once, probably before calling either of the functions posted. Any given seed will generate a predictable stream of 'random' numbers; time(0) returns a number of seconds so every call you make within 1 second will have the same seed and so will generate the same number when you later call rand

simonc
  • 41,632
  • 12
  • 85
  • 103
  • Thank you! Will try now! Thanks for quick response :D – N00byEdge Nov 01 '13 at 23:15
  • It worked great! Thank you! Now I just have to figure out what I'm doing wrong with it generating the same character in the whole string ^^ – N00byEdge Nov 01 '13 at 23:16
  • @N00byEdge Glad it helped. I've updated my answer to cover why you aren't getting random characters generated. – simonc Nov 01 '13 at 23:19
  • Also, the `for` loop and `return 1` in `randomIDChar()` are totally useless since the function returns the very first time the loop is entered. I can't even begin to guess what you want to achieve here. – syam Nov 01 '13 at 23:21
  • The return 1 was there before I built the function, forgot to remove it ;) – N00byEdge Nov 01 '13 at 23:23
  • And the for loop was creating the string, changed it, removing the loop maybe I should have done ;) – N00byEdge Nov 01 '13 at 23:24
1
v[i] = randomIDChar();

causes an undefined behavior since it attempts to write a character behind the bounds of the array (vector's internal buffer, which hasn't been previously allocated).

Also note that you don't need a vector of characters to later construct a string, you can work directly with std::string object. And also note that the way you generate the position of character produces quite skewed results, this would yield better results:

char randomIDChar(){
    static const char alphanum[] =
        "0123456789"
        "!@#$%^&*"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    static int len = 0;
    if (len == 0) {
        srand(time(0));
        len = sizeof(alphanum) - 1;
    }
    int pos = ((double)rand() / ((double)RAND_MAX + 1.0)) * len;
    return alphanum[pos];
}

std::string newUnitID(){
    const int LEN = 50;
    std::string str(LEN, ' ');
    for(int i = 0; i < LEN; i++) {
        str[i] = randomIDChar();
    }
    return str;
}

Worth to have a look at: What is the best way to generate random numbers in C++?

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167