Segmentation fault, array hell? - c++

there seemed to be a lot of people with the segmentation fault problem but I couldn't seem to find any that related to my program, if there is a thread I'm sorry, I looked through multiple though and couldn't find it.
pretty much everything so far:
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <time.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int maxLandMass = SCREEN_WIDTH * SCREEN_HEIGHT;
const int landPercentage = 30;
const int maxHeight = 200;
const int numAnts = 10;
int main(int argc, char **argv)
{
int currentLandMass = 0;
int ants[numAnts][3]={{0}}; //x,y,pDir (0123,NESW)
std::string rules[numAnts]={0};
std::string rule;
int states = 2;
std::cout << "Which rule would you like to use? ";
std::cin >> rule;
if(rule == "")
{
rule = "RL";
}
else if(rule == "RND" || rule == "rnd")
{
std::cout << "How many states? ";
std::cin >> states;
}
srand(time(NULL));
for(int i = 0;i < numAnts;i++)
{
ants[i][0] = rand() % SCREEN_WIDTH;
ants[i][1] = rand() % SCREEN_HEIGHT;
ants[i][2] = rand() % 4;
if(rule != "RND" && rule != "rnd")
{
rules[i] = rule;
}
else
{
std::string tempRule;
for(int s = 0; s < states; s++)
{
int r = rand() % 2;
if(r == 0){ tempRule += "L"; }
if(r == 1){ tempRule += "R"; }
}
rules[i] = tempRule;
}
std::cout << rules[i] << "\n";
}
SDL_Window* window = NULL;
SDL_Surface* surface = NULL;
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if( window == NULL )
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
surface = SDL_GetWindowSurface(window);
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0x00, 0x00, 0x00));
SDL_UpdateWindowSurface(window);
}
}
//Uint16 *pixels = (Uint16 *) surface->pixels;
/////////////////////////////
int grid[SCREEN_HEIGHT][SCREEN_WIDTH]={{0}};
int heights[SCREEN_HEIGHT][SCREEN_WIDTH]={{0}};
int prevState = 0;
for(int a = 0; a < numAnts; a++)
{
//TODO add stuff here
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
When it runs it should start with a console window to get some input from the user then switch to an SDL window and do its thing, but the console window tells me:
terminate called after throwing an instance of 'std::logic_error'
what():basic_string::_S_construct null not valid
I have a feeling its something to do with how I have initialised (or at least tried to) the arrays.
The part that I added last was the bit below the ////// line I made.
let me know if you will need more info, Ill get it as soon as I can, and I apologise for my programs current state, its messiness is driving me a bit mad too but (until I broke it) it worked :P

You are initializing your array of strings with zeros. That's an invalid initialization.
Interestingly, had you picked any other number, you'd get a clearer error message, telling you that you're doing an invalid conversion from int to const char* (which is a c-style string, and the closest valid input type std::string has a constructor for).
Unfortunately, the zero initialization is confusing your compiler to think you're actually assigning a pointer, which it may convert, but luckily it checks and sees that the pointer is NULL, and therefore bails out with the error message you saw: basic_string::_S_construct null not valid.
I took your code and removed all the SDL part, it compiled and reproduced the error.
I then replaced
std::string rules[numAnts]={0};
with
std::string rules[numAnts];
which uses the default constructor to create empty strings for all elements, and now it seems to work.

Related

TTF_SizeText() not returning correct values for 'i' 'j' and '1' (so far discovered) in SDL2, C++

I have a textbox class that works nicely with wider characters such as a,b,c... but with characters like 'f' and 'l' it seems to incorrectly get the sizing of those characters, yet correctly get the sizing of the others? Here is the code for the 'highlighting' of the text for the textbox class, its a bit long ill fix that up later, but should documented enough to understand easily.
void Textbox::Highlight_Text(SDL_Renderer *renderer)
{
if (clickedOn == true){
int currentCharacterWidth = 0;
int currentCharacterHeight = 0;
int totalSize = 0;
SDL_Rect currentCharacterRect;
string currentCharacter, tempText;
if (highlightedCharacters.size() >= 1){ ///To make sure only 1 thing is highlighted, in conjunction with next part
highlighted = true;
}
if (highlighted == true){ /// if a part is highlighted, and is left highlighted, next time clicked, remove the highlighting and redo it
if (EVENTS.mouseClicked == false){
resetHighlightingNextClick = true;
}
}
if (resetHighlightingNextClick == true){
if (highlighted == true){
if (EVENTS.mouseClicked == true){ ///actually remove the highlighting
highlightedCharacters.clear();
indexOfCharactersHighlighted.clear();
highlighted = false;
resetHighlightingNextClick = false;
}
}
}
for (int i=0; i < textboxText.Get_Text().size(); i++){
currentCharacter = textboxText.Get_Text()[i];
TTF_SizeText(textboxText.fonts[textboxText.fontIndex], currentCharacter.c_str(), &currentCharacterWidth, &currentCharacterHeight);
///the totalSize added to rectangle is not making it wider, its adjusting its x value offset
currentCharacterRect = {textboxText.x + totalSize, textboxText.y + int(textboxText.textSize*0.1), currentCharacterWidth, currentCharacterHeight};
totalSize += currentCharacterWidth; ///"current" size of text in loop to get x value of specific character clicked on
///If mouse is touching any of the characters in the text
if ( SDL_PointInRect(&EVENTS.mousePos, &currentCharacterRect) ){
EVENTS.Change_Cursor(SDL_SYSTEM_CURSOR_IBEAM);
if (EVENTS.mouseClicked == true){ ///Clicking on the text to highlight
if (In_Array(highlightedCharacters, currentCharacterRect.x) == false ){
highlightedCharacters.push_back(currentCharacterRect); ///If there is no duplicates
indexOfCharactersHighlighted.push_back(i); ///Get index of text being highlighted, its always in order too
}
if ( currentCharacterRect.x != highlightedCharacters[highlightedCharacters.size()-1].x){ ///So they don't stack up highlights, ie, you can remove them
/// If the mouse is not highlighting the last one, say second last on the right for example, delete the one in front of it (last one)
///Like when highlighting text with mouse, it adapts to how you move it, so it unhighlights text not being highlighted
highlightedCharacters.pop_back();
indexOfCharactersHighlighted.pop_back();
}
}
}
}///End for loop
if (highlighted == true ){
if (EVENTS.backspacePressed == true || EVENTS.currentKey != ""){
tempText = textboxText.Get_Text();
///remove highlighted characters
if (indexOfCharactersHighlighted.size() != 0){
///the range of values highlighted will always be in a sorted order
tempText.erase( Min(indexOfCharactersHighlighted) , Max(indexOfCharactersHighlighted)-Min(indexOfCharactersHighlighted)+1 ); ///erase the range of values highlighted
textboxText.Change_Text(renderer, tempText);
///once removed text, clear every highlighted related thing
highlightedCharacters.clear();
indexOfCharactersHighlighted.clear();
highlighted = false;
resetHighlightingNextClick = false;
EVENTS.backspacePressed = false;
EVENTS.currentKey = "";
}
}
}
} ///End if for clicked on
///fit with scrolling offsets
if (EVENTS.scrolled == true){
for (int p=0; p < highlightedCharacters.size(); p++){
highlightedCharacters[p].y += EVENTS.scrollVal;
}
}
///Drawing the highlighted text
if (highlighted == true && clickedOn == true){
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 55,60,65, 75);
for (int j=0; j < highlightedCharacters.size(); j++){
SDL_RenderFillRect(renderer, &highlightedCharacters[j]);
}
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
}
///when clicked off textbox, clear everything/highlighting
if (clickedOn == false){
highlightedCharacters.clear();
indexOfCharactersHighlighted.clear();
highlighted = false;
}
}
For reference in the font passed in, here is how i obtain it in the text class
fontIndex = textSize-lowestFontSize -1;
///One time setups
if (numOfInstances == 1){
try{
TTF_Init();
//cout << "Initialised ttf" << endl;
}
catch (exception &err){
cout << "Could not initialise ttf for text \"" << text << "\". Error from SDL is: " << TTF_GetError() << ". Error from C++ is: " << err.what() << endl;
}
for (int i=lowestFontSize; i <= highestFontSize; i++){
TTF_Font *currentFont = TTF_OpenFont(fontType.c_str(), i);
if (!currentFont){
cout << "Error with font in text \"" << txt << "\" Error is: " << SDL_GetError() << endl;
}
fonts.push_back(currentFont);
}
}
and so if i pass in, say 25 as my text size, i have my lowestFontSize = 10 and highestFontSize = 100, so the index i need for size 25 would be (25-10 -1 = 14), as indexing begins at 0, which is that first line before i create my static vector of fonts in the text class. Here is a snippet of what i'm trying to explain:
This is clearly working properly.
But now, it is completely inaccurate. If i select a random character towards the end of the text, it is not correctly highlighted, only from the beginning the first one looks pretty much perfect, but then it seems as if the inaccuracy is compounded, hence making the total grey highlighting much wider than it is supposed to be.
The problem with your method is that individual character widths are meaningless. The renderer adjusts them depending on context (their neighbours in the rendered string). So the width of i in the rendered string bit is not necessarily the same as the width of i in the rendered string fil.
The method to find text selection coordinates needs to take context into account.
Say we have the width of the three strings:
prefixWidth is the size of the prefix (the original line of text up to but not including the selection)
selWidth is the width of the selection itself
totalWidth is the width of the prefix and the selection concatenated
(we don't care about the portion after the selection). The first two widths will be close to the third, but will not add up because of the kerning between the last character of the prefix and the first character of the selection. The difference is the correction you need to apply to the X coordinate of the rendered selection. So we need to start rendering selection at the X coordinate which is not prefixWidth, but
prefixWidth + (totalWidth - (prefixWidth + selWidth))
which is the same as
totalWidth - selWidth
so you don't really need to calculate prefixWidth at all.
A full (semi-)working example program below. The arguments are (1) font file full path (2) font size (3) string to render (4) selection start (5) selection length. The selection is rendered on top of the original text, shifted 1 pixel down and right, so it is easy to see if there is any deviation.
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
char* substr(const char* src, int fromChar, int subLen)
{
if (subLen < 0 || fromChar < 0 || fromChar + subLen > (int)strlen(src))
{
fprintf (stderr, "invalid substring\n");
exit (EXIT_FAILURE);
}
char* z = (char*)malloc(subLen);
strncpy(z, src + fromChar, subLen);
z[subLen] = '\0';
return z;
}
void textExtent(TTF_Font* font, const char* text,
int fromChar, int subLen, int* w, int* h)
{
int l = strlen(text);
if (subLen == -1) subLen = l;
if (fromChar < 0 || subLen > l)
{
fprintf (stderr, "Bad text extent\n");
exit (EXIT_FAILURE);
}
char* z = substr(text, fromChar, subLen);
TTF_SizeUTF8(font, z, w, h);
free(z);
}
int textWidth(TTF_Font* font, const char* text,
int fromChar, int subLen)
{
int w, h;
textExtent(font, text, fromChar, subLen, &w, &h);
return w;
};
int main(int argc, char ** argv)
{
bool quit = false;
SDL_Event event;
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
if (argc != 6)
{
fprintf (stderr, "usage: %s font text from length\n", argv[0]);
exit(EXIT_FAILURE);
}
const char* fontpath = argv[1];
int fontSz = atoi(argv[2]);
const char* txt = argv[3];
int from = atoi(argv[4]);
int len = atoi(argv[5]);
int tsize = strlen(txt);
if (from < 0 || from + len >= tsize)
{
fprintf (stderr, "Invalid text portion to highlight\n");
exit (EXIT_FAILURE);
}
if (fontSz < 2 || fontSz > 300)
{
fprintf (stderr, "Invalid font size\n");
exit (EXIT_FAILURE);
}
// open font to render with
TTF_Font * font = TTF_OpenFont(fontpath, fontSz);
if (!font)
{
fprintf (stderr, "Could not open font %s\n", fontpath);
exit (EXIT_FAILURE);
}
// Query text size
int textW, textH;
textExtent(font, txt, 0, -1, &textW, &textH);
SDL_Window * window = SDL_CreateWindow("SDL_ttf in SDL2",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, textW, textH, 0);
// Query selection coords
//
int selWidth = textWidth(font, txt, from, len);
int totalWidth = textWidth(font, txt, 0, from+len);
// Render portions of text
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Color color = { 255, 128, 0, 0 };
SDL_Surface * surface = TTF_RenderUTF8_Blended(font, txt, color);
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
SDL_Rect dstrect = { 0, 0, textW, textH };
SDL_Color color2 = { 0, 128, 255, 128 };
char* s = substr(txt, from, len);
SDL_Surface * surface2 = TTF_RenderUTF8_Blended(font, s, color2);
free(s);
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
SDL_Texture * texture2 = SDL_CreateTextureFromSurface(renderer, surface2);
SDL_SetTextureAlphaMod(texture2, 128);
SDL_SetTextureBlendMode(texture2, SDL_BLENDMODE_BLEND);
SDL_Rect dstrect2 = {totalWidth - selWidth + 1, 1, selWidth, textH };
while (!quit)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
quit = true;
break;
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
SDL_RenderCopy(renderer, texture2, NULL, &dstrect2);
//Update screen
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_DestroyTexture(texture);
SDL_FreeSurface(surface);
TTF_CloseFont(font);
TTF_Quit();
SDL_Quit();
return 0;
}

Xlib test window names

I'm trying to get control of the the Xterm with Xlib.
For that i'm making a Xterm with a strange title. After I list all window and check they names. But something is bugged the nammes of my Xterm does not appear when they are listed. Here is the code for list all window :
void CMD::getWindowTerminal()
{
Atom a = XInternAtom(m_display, "_NET_CLIENT_LIST", true);
Atom actualType;
int format;
unsigned long numItems, bytesAfter;
unsigned char *data = 0;
int status = XGetWindowProperty(m_display, m_root_win, a, 0L, (~0L), false,
AnyPropertyType, &actualType, &format, &numItems,
&bytesAfter, &data);
if (status >= Success && numItems)
{
long *array = (long*) data;
for (unsigned long k = 0; k < numItems; k++)
{
// get window Id:
Window w = (Window) array[k];
char* name = '\0';
status = XFetchName(m_display, w, &name);
if (status >= Success)
{
std::cout << w << " " << name << std::endl;
if (name == NULL)
{
m_window_terminal = w;
std::cout << "TERMINAL FOUND" << std::endl;
}
}
XFree(name);
}
XFree(data);
}
}
I cannot reproduce the error; your code finds my xterm windows. Are you querying the window of an xterm you only just spawned? If so, you might have a race condition in that you try to find the window before xterm had a chance of making it. In that case, a crummy solution would be to wait a bit and try again several times.
If that is not the case, I can only speculate (more) about causes (my speculations involve a misbehaving window manager or very old software), but perhaps I can suggest a solution: if the xterm doesn't show up in the root window's _NET_CLIENT_LIST, let's dig directly into the window tree and see if we can find it there. This bit of C code (porting to C++ should not be difficult, and anyway it's enough to try it out) traverses the window tree recursively with XQueryTree, so it queries all windows:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
Window window_from_name_search(Display *display, Window current, char const *needle) {
Window retval, root, parent, *children;
unsigned children_count;
char *name = NULL;
/* Check if this window has the name we seek */
if(XFetchName(display, current, &name) > 0) {
int r = strcmp(needle, name);
XFree(name);
if(r == 0) {
return current;
}
}
retval = 0;
/* If it does not: check all subwindows recursively. */
if(0 != XQueryTree(display, current, &root, &parent, &children, &children_count)) {
unsigned i;
for(i = 0; i < children_count; ++i) {
Window win = window_from_name_search(display, children[i], needle);
if(win != 0) {
retval = win;
break;
}
}
XFree(children);
}
return retval;
}
// frontend function: open display connection, start searching from the root window.
Window window_from_name(char const *name) {
Display *display = XOpenDisplay(NULL);
Window w = window_from_name_search(display, XDefaultRootWindow(display), name);
XCloseDisplay(display);
return w;
}
Since it handles all windows, your xterm window has to be among them. If it is not, refer back to the beginning (the bit about a possible race condition). And if that's not it, then something's very strange.

Getting Eclipse's C++ parser to work with Emscripten

I'm having a few problems with Eclipse's C++ parser. I've been using it with Emscripten and found the code completion, call hierarchy, documentation popup, code analysis and related features to be very useful, but it's been bothering me that the parser isn't totally working. Especially with this new problem with using vectors.
The first parsing error is on std::vector<SDL_Rect> box; with the error being:
Symbol 'vector' could not be resolved
And then on emscripten_set_main_loop(game_loop, 60, 1); I get this error:
Function 'usleep' could not be resolved
Here's the full code:
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <emscripten.h>
#include <stdarg.h>
#include <libcxx/vector>
///GLOBAL VARIABLES
SDL_Surface* bitmap;
SDL_Surface* screen;
SDL_Rect source;
SDL_Rect destination;
///second sprite
SDL_Surface* bitmap2;
SDL_Rect source2;
SDL_Rect destination2;
/// Side Scrolling variables:
SDL_Rect camera;
SDL_Rect offset;
SDL_Rect offset2;
int level_width = 480 * 5;
int level_height = 640;
bool gameRunning = true;
class buttonpresses {
public:
bool leftButton;
bool rightButton;
bool jumpButton;
};
int movementspeed = 5;
int jumpspeed = 2;
bool jumpenabled = false;
int jumpduration = 0;
int maxjump = 20;
int leftmomentum = 1;
int rightmomentum = 1;
int lastdestination;
int countDestination = 0;
int maxmomentum = 5;
buttonpresses charactermovement;
/// Collision detection
std::vector<SDL_Rect> box;
///MAIN LOOP
void game_loop() {
// EVENT HANDLING
SDL_PumpEvents();
Uint8 *keystate = SDL_GetKeyboardState(NULL);
if (keystate[SDLK_ESCAPE]) {
gameRunning = false;
printf("Game Stopping!!!!!!\n");
SDL_Quit();
exit(0);
}
if (keystate[SDLK_LEFT]) {
// printf("Left Key\n");
charactermovement.leftButton = true;
}
if (keystate[SDLK_LEFT] == false) {
charactermovement.leftButton = false;
}
if (keystate[SDLK_RIGHT]) {
// printf("Right Key\n");
charactermovement.rightButton = true;
}
if (keystate[SDLK_RIGHT] == false) {
charactermovement.rightButton = false;
}
if (keystate[SDLK_SPACE]) {
// printf("Space Key\n");
charactermovement.jumpButton = true;
}
if (keystate[SDLK_SPACE] == false) {
charactermovement.jumpButton = false;
}
// printf("Game Running..\n");
// LOGIC
//character movement
if (charactermovement.rightButton) {
destination.x = destination.x + movementspeed;
}
if (charactermovement.leftButton) {
destination.x = destination.x - movementspeed;
}
if (charactermovement.jumpButton && jumpenabled) {
destination.y = destination.y - jumpspeed;
jumpduration++;
}
destination.x = destination.x + rightmomentum - leftmomentum;
if (destination.y >= 200) {
jumpenabled = true;
// printf ("jump enabled\n");
}
if (jumpduration >= maxjump) {
jumpenabled = false;
}
if (destination.y >= 200) {
// printf ("destination y:");
// printf ("%d\n", destination.y);
jumpduration = 0;
}
//if (jumpenabled != true){
// printf ("jump disabled\n");
//}
//if (jumpenabled == true){
// printf ("jump enabled\n");
// printf ("jump duration: ");
// printf ("%d\n", jumpduration);
//}
//momentum
//save position every 5 interations
if (countDestination > 5) {
lastdestination = destination.x;
countDestination = 0;
} else {
countDestination++;
}
//printf ("last location: ");
//printf ("%d\n", destination.x);
//
//printf ("current location: ");
//printf ("%d\n", lastdestination);
// increase momentum in direction your moving in (relative to previous location)
if (lastdestination > destination.x) {
// printf ("right if running \n ");
if (rightmomentum > 0) {
rightmomentum--;
} else if (leftmomentum < maxmomentum) {
leftmomentum++;
}
}
if (lastdestination < destination.x) {
// printf ("left if running \n ");
if (leftmomentum > 0) {
leftmomentum--;
} else if (rightmomentum < maxmomentum) {
rightmomentum++;
}
}
if (lastdestination == destination.x) {
if (leftmomentum > 0) {
leftmomentum--;
}
if (rightmomentum > 0) {
rightmomentum--;
}
}
printf("left momentum: ");
printf("%d\n", rightmomentum);
printf("right momentum: ");
printf("%d\n", leftmomentum);
//gravity
if (destination.y <= 200) {
destination.y++;
}
offset.x = destination.x - camera.x;
offset2.x = destination2.x - camera.x;
offset.y = destination.y - camera.y;
offset2.y = destination2.y - camera.y;
// RENDERING
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(bitmap, &source, screen, &offset);
// RENDER SECOND SPRITE
SDL_BlitSurface(bitmap2, &source2, screen, &offset2);
//blank screen
SDL_Flip(screen);
camera.x++;
}
int main() {
SDL_Init( SDL_INIT_VIDEO);
// LOAD FILES
bitmap = IMG_Load("ninjagaiden3sheet1.png");
screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE | SDL_DOUBLEBUF);
/// camera variables
camera.x = 0;
camera.y = 0;
camera.w = 640;
camera.h = 480;
/// end camera variables
// Part of the bitmap that we want to draw
source.x = 37;
source.y = 4;
source.w = 17;
source.h = 32;
// Part of the screen we want to draw the sprite to
destination.x = 100;
destination.y = 100;
destination.w = 65;
destination.h = 44;
//// second sprite
bitmap2 = IMG_Load("bat_transparent.png");
source2.x = 24;
source2.y = 63;
source2.w = 65;
source2.h = 44;
destination2.x = 940;
destination2.y = 100;
destination2.w = 65;
destination2.h = 44;
//// end second sprite
lastdestination = destination.x;
offset = destination;
offset2 = destination2;
charactermovement.leftButton = false;
charactermovement.rightButton = false;
charactermovement.jumpButton = false;
//START MAIN LOOP
emscripten_set_main_loop(game_loop, 60, 1);
return 0;
}
My includes tab for C++ in the "Paths and Symbols" properties looks like:
C:\Program Files\Emscripten\emscripten\1.12.0\system\include
C:\Program Files\Emscripten\emscripten\1.12.0\system\include\libc
C:\Program Files\Emscripten\emscripten\1.12.0\system\include\emscripten
C:\Program Files\Emscripten\emscripten\1.12.0\system\include\libcxx
In the Indexer settings I have the following enabled:
Index source files not included in the build
Index unused headers
Index all header variants
Index source and header files opened in editor
Allow heuristic resolution of includes
Skip files larger than: 8 MB
Does anyone know what's going on? Or what I can do to fix it?
Update:
I've fixed the error on parsing std::vector. It turns out that some of llvm/clang libraries use _LIBCPP_BEGIN_NAMESPACE_STD and _LIBCPP_END_NAMESPACE_STD definitions instead of using namespace std; and those defines are invisible to the parser unless __clang__ is defined.
So the solution is to go into the "Symbols" tab for C++ in the "Paths and Symbols" properties and add:
__clang__
In the "Add" dialog that pops up just put it in the Name: input field and press OK. This will also add many of the missing std namespace functions like cout cin etc.
I haven't found a fix for the usleep/emscripten_set_main_loop issue yet but this should be good enough to get the IDE's code completion and several related features to work. Though I'm still having some weird complicated parser issues with Eclipse so I think I'm going to abandon the search for a solution here and work with NetBeans for which I think I have every thing set up.

boost::interprocess message queue Race Condition on creation?

I am trying to debug sporadic access violations that occur inside a boost::interprocess message queue. (access violation reading an address in the shared memory region).
Environment: boost 1.54, VC++2010. Occurs in both Debug & Release builds.
It always occurs on or about line 854 (in case of reception) in message_queue.hpp:
Comments were added by me
recvd_size = top_msg.len; // top_msg points to invalid location
Or line 756 (in case of sending)
BOOST_ASSERT(free_msg_hdr.priority == 0); // free_msg_hdr points to invalid location
It appears as though this is related to the message queue creation. If a message queue is created "properly" (i.e. without the possible race condition), the error never occurs.
Otherwise it might occur on timed_receive() or timed_send() on the queue at seemingly random times.
I came up with a short example that represents the problem:
Unfortunately I cannot run it on Coliru, since it requires two processes.
One has to be started without any parameters, the second with any single parameter.
After a number of runs, one of the processes will crash in message_queue.
#include <iostream>
#include <boost/interprocess/ipc/message_queue.hpp>
#include <boost/thread.hpp>
#include <boost/assert.hpp>
#include <boost/date_time.hpp>
using namespace boost::interprocess;
using namespace boost::posix_time;
using boost::posix_time::microsec_clock; // microsec_clock is ambiguous between boost::posix_time and boost::interprocess. What are the odds?
int main(int argc, wchar_t** argv)
{
while(true)
{
int proc = 0;
message_queue* queues[2] = {NULL, NULL};
std::string names[] = {"msgq0", "msgq1"};
if(1 == argc)
{
proc = 0;
message_queue::remove(names[0].c_str());
if(NULL != queues[0]) { delete queues[0]; queues[0] = NULL; }
queues[0] = new message_queue(open_or_create, names[0].c_str(), 128, 10240);
bool bRet = false;
do
{
try
{
if(NULL != queues[1]) { delete queues[1]; queues[1] = NULL; }
queues[1]=new message_queue(open_only, names[1].c_str());
bRet = true;
}
catch(const interprocess_exception&)
{
//boost::this_thread::sleep(boost::posix_time::milliseconds(2));
delete queues[1];
queues[1] = NULL;
continue;
}
}while(!bRet);
}
else
{
proc = 1;
message_queue::remove(names[1].c_str());
if(NULL != queues[1]) { delete queues[1]; queues[1] = NULL; }
queues[1] = new message_queue(open_or_create, names[1].c_str(), 128, 10240);
bool bRet = false;
do
{
try
{
if(NULL != queues[0]) { delete queues[0]; queues[0] = NULL; }
queues[0]=new message_queue(open_only, names[0].c_str());
bRet = true;
}
catch(const interprocess_exception&)
{
//boost::this_thread::sleep(boost::posix_time::milliseconds(2));
delete queues[0];
queues[0] = NULL;
continue;
}
}while(!bRet);
}
long long nCnt = 0;
for(int i = 0; i < 1; ++i)
{
if(proc)
{
std::string sOut;
sOut = "Proc1 says: Hello ProcA " + std::to_string(nCnt) + " ";
sOut.resize(10230, ':');
for(int n = 0; n < 3; ++n)
{
queues[1]->timed_send(sOut.data(), sOut.size(), 0, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
}
bool bMessage = false;
for(int n = 0; n < 3; ++n)
{
size_t nRec; unsigned int nPrio;
std::string sIn; sIn.resize(10240);
bMessage = queues[0]->timed_receive(&sIn[0], 10240, nRec, nPrio, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
if(bMessage)
{
sIn.resize(nRec);
//std::cout << sIn << " ";
}
}
if(bMessage)
{
//std::cout << std::endl;
}
}
else
{
std::string sOut;
sOut = "Proc0 says: Hello Procccccccdadae4325a " + std::to_string(nCnt);
sOut.resize(10240, '.');
for(int n = 0; n < 3; ++n)
{
queues[0]->timed_send(sOut.data(), sOut.size(), 0, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
}
bool bMessage = false;
for(int n = 0; n < 3; ++n)
{
size_t nRec; unsigned int nPrio;
std::string sIn; sIn.resize(10240);
bMessage = queues[1]->timed_receive(&sIn[0], 10240, nRec, nPrio, ptime(boost::posix_time::microsec_clock::universal_time()) + milliseconds(1));
if(bMessage)
{
sIn.resize(nRec);
//std::cout << sIn << " ";
}
}
if(bMessage)
{
//std::cout << std::endl;
}
}
nCnt++;
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
}
return 0;
}
I am still thinking I might be doing something wrong, since I cannot find anything about this problem anywhere else, and the boost libraries are normally very good.
Is there anything I might be doing wrong with the usage of the message_queue in this example?
I don't think that both processes using open_or_create is a supported idiom. Are you aware of this thread on the mailing list? I can't find more discussions so it looks to me like lifetime management wasn't eventually considered necessary to add.
Thus you'll need to synchronise the creation manually with boost::interprocess or possibly by having one of the processes retrying to open_only the queue until the other process creates it.

C++/SDL loading array of strings from lua

I'm using lua to load my maps in C++/SDL and i have an array in lua that determines the location of the tile image but I don't know how to transfer it to an array in C++ I've looked for an explanation but they all deal with ints and the lua files only have 1 array and for some reason the code doesn't work this is probably a stupid question but yeah
Here is the code:
Map.lua
Tile = {}
--opens file and reads it
local file = io.open("../Maps/Map.txt")
local n = 0
while(n <= 494) do
Tile[n] = file:read(1)
n = n+1
end
file:close()
--end of reading file
n = 0
local x = 0
-- creates a new array for the tiles
whatsTile = {}
isSolid = {}
--sets the tiles to their specific image
while(n <= 494) do
if(Tile[n] ~= "\n" and Tile[n] ~= "\r") then
if(Tile[n] == '0') then
--This is the array in lua that holds the file location
whatsTile[x] = "../GameResources/Pictures/Tile1.bmp"
--sets this tile to non solid
isSolid[x] = 0
end
--You can add new tiles just set their number and, add a directory for the Bitmap image.
--Make sure you set the directory based on where the executable file is, not this script.
x = x+1
end
n = n+1
end
main.cpp
#include <SDL/SDL.h>
#include <string>
#include <iostream>
#include <lua.hpp>
#include <fstream>
using namespace std;
extern "C"{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <luaconf.h>
}
void loadMapLua();
//This is the array i want to transfer the values into
string whatsTile[475];
int main(int argc, char** argv){
ofstream myfile;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Event event;
loadMapLua();
SDL_Surface* Screen = SDL_SetVideoMode(800, 608, 32, SDL_SWSURFACE);
SDL_Surface* BackGround = SDL_LoadBMP("../GameResources/Pictures/BackGround.bmp");
SDL_Surface* Tiles[475];
const char* c;
SDL_Rect Tile[475];
int n = 0;
while(n < 475){
c = whatsTile[n].c_str();
Tiles[n] = SDL_LoadBMP(c);
Tile[n].w = 32;
Tile[n].h = 32;
Tile[n].x = n*32;
Tile[n].y = (n/25)*32;
n ++;
}
n = 0;
myfile.open("trolls.txt");
myfile << whatsTile[0] << endl;
myfile.close();
bool gameRunning = true;
while(gameRunning){
while(SDL_PollEvent(&event)){
if(event.type == SDL_QUIT){
gameRunning = false;
}
}
SDL_FillRect(Screen, 0, SDL_MapRGB(Screen->format, 255, 255, 255));
SDL_BlitSurface(BackGround, NULL, Screen, NULL);
while(n < 475){
SDL_BlitSurface(Tiles[n], NULL, Screen, &Tile[n]);
n ++;
}
SDL_Flip(Screen);
}
SDL_Quit();
return 0;
}
void loadMapLua(){
lua_State* Map = lua_open();
luaL_openlibs(Map);
luaL_dofile(Map, "../GameResources/LuaScripts/Map.lua");
lua_pushnil(Map);
lua_close(Map);
}
You cannot get whole array at once.
Use looping to get all the strings.
string whatsTile[475];
int len_whatsTile = 0;
void loadMapLua(){
lua_State* L = lua_open();
luaL_openlibs(L);
luaL_dofile(L, "../GameResources/LuaScripts/Map.lua");
lua_getglobal(L, "whatsTile");
int Index = 0;
do {
lua_pushinteger(L, Index++);
lua_gettable(L, -2);
if (lua_isnil(L, -1))
Index = 0;
else
whatsTile[len_whatsTile++].assign(lua_tostring(L, -1));
lua_pop(L, 1);
} while (Index > 0);
lua_close(L);
}