Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Problem with running a big-array-of-pixels app  (Read 5620 times)

0 Members and 1 Guest are viewing this topic.

-Nautilus-

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Problem with running a big-array-of-pixels app
« on: July 20, 2016, 06:34:38 pm »
So, this is obviously not my real app, but i managed to isolate it to this piece of code.

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <cstdio>

int main()
{
    long int W;
    scanf("%d", &W);
    const long int H = W;

    sf::Texture texture;
    sf::Sprite sprite;

    if(!texture.create(W, H)) throw "ERR";

    sf::Uint8 pixels[W*H*4];
    texture.update(pixels);
    sprite.setTexture(texture);

    return 0;
}


In the actual program, I'm manipulating an array of pixels pixel-by-pixel.
I've tested for W=716 and lower values, and it presented the standard "Status 0" stuff at the end.
But for W=717 and larger values, a box pops up, where you can read:

"ProblemProject.exe stopped working
Windows is searching for a solution to the problem..."

and then another one saying:

"ProblemProject.exe stopped working
Windows is collecting information about the problem. This process might take several minutes..."

and finally one saying:

"ProblemProject.exe stopped working
A problem led to the program to stop working correctly. Windows will close the program and warn you if there is a possible solution."

I click a "Close program" button, and the Console presents the message:

"Process returned 255 (0xFF)   execution time : 9.685 s
Press any key to continue."

I've tested the code for a full-window (red-coloured xd) rectangle shape and it worked fine for every value of W.

I'm using static (and static debug as well) versions of all the SFML 2.3.2 libraries (both with -s and -s-d i get the same thing), and using
CodeBlocks Release 13.12 rev 9501 (2013/12/25 19:25:45) gcc 4.7.1 Windows/unicode - 32 bit

I'm working on Windows10, and my GPU is NVIDIA GEFORCE GTX 950M.

Please help me, I'm almost certain it must be a begginer's issue, but I still couldn't find any related post.
« Last Edit: July 20, 2016, 06:38:27 pm by -Nautilus- »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #1 on: July 20, 2016, 07:22:55 pm »
Quote
sf::Uint8 pixels[W*H*4];
This is invalid C++. And since it is allocated on the stack, which has a limited size, it starts to crash after a certain size, as you noticed. Instead, you should use std::vector.
Laurent Gomila - SFML developer

-Nautilus-

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #2 on: July 20, 2016, 07:37:08 pm »
I have replaced that statement by std::vector<sf::Uint8> pixels(W*H*4);, but it says:
"error: no matching function for call to 'sf::Texture::update(std::vector<unsigned char>&)".

(actually, sf::Texture::update has no overload for std::vector<>, but only for sf::Uint8, Image and Window)

Also, I've experimented an isolated sf::Uint8 array, and memory is not the problem, since I've tested declarating such an array with 2000*2000*4 elements, and it works fine.

Also, i've tracked the problem to the statement texture.update(pixels);. Still dont understand why.

btw, that statement is not illegal since i've used it in the app i'm developing and it worked fine up to 716*716*4.
« Last Edit: July 20, 2016, 07:53:48 pm by -Nautilus- »

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Problem with running a big-array-of-pixels app
« Reply #3 on: July 20, 2016, 08:50:19 pm »
Try passing a pointer to the data of the vector rather than the vector itself.

Either of these should work:
  • pixels.data()
  • &pixels.front()
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #4 on: July 20, 2016, 08:56:31 pm »
Quote
Also, I've experimented an isolated sf::Uint8 array, and memory is not the problem, since I've tested declarating such an array with 2000*2000*4 elements, and it works fine.
Depends where you declare it.

Quote
btw, that statement is not illegal since i've used it in the app i'm developing and it worked fine up to 716*716*4.
It is illegal. Some compilers allow it (as a non-standard extension), mostly because it is valid in C. Compile with the -pedantic flag (gcc) and you'll see the difference.
Laurent Gomila - SFML developer

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #5 on: July 20, 2016, 10:23:52 pm »
Quote
btw, that statement is not illegal since i've used it

Just because one compiler accepts it does not mean it is valid.
Not all compilers implement the standard correctly. Compilers have bugs. Compilers have extentions to the language. Compilers may accept broken code and just print a warning (or not). Etc etc.
This is why you should always build your code with multiple compilers on multiple platforms with high warning levels enabled (and run other tools (like clang tidy, cppcheck - and others)) to be (reasonably) sure that your code is standard compliant and portable.

I recommend always building all commits with gcc, clang, VS (and sometimes icc) on (at least) Linux and Windows, with (at least) "-Wall -Wextra" (or equivalent "/W4"). More is better... It catches real bugs and keeps your code working broadly :-) and it can be completely automated to happen in the background every time you do a "git commit" :-)
  This is what I do myself - and it's worth it in the long run spending a few hours to set up a few virtual machines and a CI system integrated with you DVCS - it pays for itself many times over over the years.
« Last Edit: July 20, 2016, 10:28:46 pm by Jesper Juhl »

jamesL

  • Full Member
  • ***
  • Posts: 124
    • View Profile
Re: Problem with running a big-array-of-pixels app
« Reply #6 on: July 21, 2016, 12:07:19 am »
...
This is why you should always build your code with multiple compilers on multiple platforms with high warning levels enabled (and run other tools (like clang tidy, cppcheck - and others)) to be (reasonably) sure that your code is standard compliant and portable.

I recommend always building all commits with gcc, clang, VS (and sometimes icc) on (at least) Linux and Windows, with (at least) "-Wall -Wextra" (or equivalent "/W4"). More is better... It catches real bugs and keeps your code working broadly :-) and it can be completely automated to happen in the background every time you do a "git commit" :-)
  This is what I do myself - and it's worth it in the long run spending a few hours to set up a few virtual machines and a CI system integrated with you DVCS ...

LOL
no hobbyist gamer has time for that
nor the need to do it

if you're the author of library like SFML or Thor or SFGUI then yeah, but if you're making a small game for yourself and friends that's hardly necessary

hey, let me set up a couple of virtual machines and compile PONG on linux, windows 10 and windows 7 and use gcc and VS just to make sure my PONG code is all compliant
LOL


-Nautilus-

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #7 on: July 21, 2016, 01:18:10 am »
Thanks alot, the pointer worked.
I'll try to see those compiler stuff, but I was trying not to go really deep into that.

So, basically, it is always best to use a std::vector instead of array, right?
I guess that could be translated to reality as "No-one uses arrays of pixels, just vectors". it is very important to know what are the current standard ways to do stuff. For instance, i first met arrays and then vectors, but as soon as i met vectors i abandoned arrays, as vectors would do the same as arrays and they are more dynamic. so now even for fixed arrays, i replace arrays for vectors.

Another question... As some funny pic states, programmers say "It doesnt work. Why? / It works. Why?"
So why doesnt an array of pixels work?

Mortal

  • Sr. Member
  • ****
  • Posts: 284
    • View Profile
Re: Problem with running a big-array-of-pixels app
« Reply #8 on: July 21, 2016, 05:24:08 am »
So, basically, it is always best to use a std::vector instead of array, right?
I guess that could be translated to reality as "No-one uses arrays of pixels, just vectors". it is very important to know what are the current standard ways to do stuff. For instance, i first met arrays and then vectors, but as soon as i met vectors i abandoned arrays, as vectors would do the same as arrays and they are more dynamic. so now even for fixed arrays, i replace arrays for vectors.
in most cases the answer is yes vector is prefered over array. so if the image data is fairly small like couple of KB, yeah it is safe to use array and you are already know the limit in your machine if you go with array. but for C++ standard, actually i couldn't find reference that support it is illegal. but after searching, it turns out the standard doesn't guarantee the array will be created in stack. because, it is dependant on implementation, and according to wikipedia there are few cases here to implement array with big size like so:

//sf::Uint8 a[2000*2000*4]; // worked - global scope
//static sf::Uint8 a[2000*2000*4]; // worked - global scope
int main()
{
    //static sf::Uint8 a[2000*2000*4]; // worked - local scope
    //sf::Uint8 a[20000*20000*4]; // doesn't worked - local scope
}

Another question... As some funny pic states, programmers say "It doesnt work. Why? / It works. Why?"
So why doesnt an array of pixels work?
well, i think we need a computer hardware engineer to answer it  :-\
« Last Edit: July 21, 2016, 05:47:00 am by Mortal »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #9 on: July 21, 2016, 08:25:53 am »
Quote
So, basically, it is always best to use a std::vector instead of array, right?
No. you must first identify what you need, and then choose the best data structure accordingly. Here, you need heap allocation (because the stack is too small to hold your big array). Heap allocation is done with the new/delete keywords in C++, but this is too unsafe and low-level, so the standard library offers a std::vector wrapper that is safe and easy to use.

Other use cases will most likely require other containers. Sometimes you'll rather need std::array, or std::list, or std::set, etc. In your case you could also have used a std::unique_ptr<sf::Uint8[]>. There's no "standard way of doing things", you must know what the standard library offers, and pick the tools that best suit your needs.

Quote
So why doesnt an array of pixels work?
As already stated, the stack has a limited size, you can't allocated tons of MB on it. If this is not clear for you, you can read more about stack/heap storage. This is an important concept, especially in C++ where you directly have to deal with these two kind of storage.
Laurent Gomila - SFML developer

-Nautilus-

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Problem with running a big-array-of-pixels app
« Reply #10 on: July 22, 2016, 11:22:13 pm »
ok now i get it, i was just ignoring the fact texture and sprite would take space in the stack, im really sorry...
i know this question has nothing to do with sfml, but you said i could store the array in the heap, but i should better use vector cause its safe.

what do u mean by 'safe'? i guess you mean std::vector is still stored in the stack, and it is still safer than an array stored in the heap.

1 more question: most of the time, a function that takes an array or an array pointer can also take a vector or a vector pointer?

Hapax

  • Hero Member
  • *****
  • Posts: 3346
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Problem with running a big-array-of-pixels app
« Reply #11 on: July 23, 2016, 01:00:57 am »
what do u mean by 'safe'? i guess you mean std::vector is still stored in the stack, and it is still safer than an array stored in the heap.
An std::vector is stored on the stack but the actual data is stored on the heap. Using an std::vector is much safer when compared to using the heap manually.

1 more question: most of the time, a function that takes an array or an array pointer can also take a vector or a vector pointer?
No, because std::vector, std::array and c-style arrays are all different types. As with before, though, you can pass the data part of an std::vector or std::array as if it was an array.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*