Open Side Menu Go to the Top

01-09-2013 , 08:45 AM
Quote:
Originally Posted by e i pi
lol are you just trying to create as many different types of errors as possible or are you actually just confused?
I'm sort of confused because I was supposed to 'break' a program and the way he said to do so didn't work. It's still not working (I want a compiler crash), but I think it is interesting to see how you can dig so many holes. Explicit type-declaration is a totally new terrain for me and it's interesting how you can have the same data throw so many different type-errors.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
01-09-2013 , 09:57 AM
Code:
#include <stdio.h>

int main(int argc, char *argv[]) {

	char name[4] = {'a'};
	char new[4] = {'b'};
	// name with no terminal '\0'
	name[0] = 'a';
	name[1] = 'a';
	name[2] = 'a';
	name[3] = 'a';

	new[0] = 'b';
	new[1] = 'r';
	new[2] = 'o';
	new[3] = 'k';

	printf("use new so no warnings  %c\n", new[0]);

	printf("name each: %c %c %c %c\n",
		name[0], name[1],
		name[2], name[3]);

	// print the name like a string
	printf("name: %s\n", name);


	return 0;
}
output,

Quote:
$ make arrayoverflow
cc -Wall -g arrayoverflow.c -o arrayoverflow
$ ./arrayoverflow
use new so no warnings b
name each: a a a a
name: aaaabrok
i broke it. weird, i tried a larger array to spell out 'broken' but any array bigger than 4 characters wouldn't cause this error. i guess it put it somewhere else in memory.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 10:26 AM
This is what I get:

Code:
$ make wtf
cc -Wall -g    wtf.c   -o wtf

$ ./wtf
use new so no warnings  b
name each: a a a a
name: aaaa\300\204
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 10:55 AM
Arrays in C can almost be thought of as just pointers. When you do stuff like: foo[2] you are really just doing pointer arithmetic under the hood. The bracket notation is just syntactic sugar.

They are just a sequence of bytes lined up in a row. A character type takes up 1 byte so it's easy to see where it ends, it ends after 1 byte. No need for a \0.

A string needs a trailing \0 because it's a sequence of bytes of unknown length, also known as a char*. The only way a human can know that a string is finished is checking for \0.

Think about how you would implement strlen() by yourself. It would likely involve going through the array 1 character at a time until you hit \0, and now you know the length assuming you were incrementing a counter along the way.

Due to how the stack works you may or may not segfault if you go out of bounds on an array. C has no auto-check on that, so it's up to you to not be a goofball. Results will vary. In the "broken" example you would likely segfault if you made the "broken" string a few dozen or a 100ish characters but it wouldn't be guaranteed, your chances would just go up.

Edit:

To be super clear (and maybe to check to make sure I'm right because I'm not 100% on this), the array living in main() is living in main's stack space. When you access an array outside of its bounds, you're actually climbing up in memory even though the stack can be thought of as growing downwards conceptually.

So when you read a higher than expected value you are climbing up (backtracking) up the stack until you reach another layer of memory reserved for your application. This is still ok because you own that memory space. You'll only crash if you read so many bytes that it places you outside the scope of your app, and then you'll segfault. Since we're dealing with pointers here I don't think it matters what type of data is contained there because a pointer is a pointer in the end, it's just pointing to something.

Is that right?

Last edited by Shoe Lace; 01-09-2013 at 11:12 AM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 01:07 PM
Functional programmers:
How would one go about mixing FP and REST? I've only really thought of REST in an OO context.

Feel free to use any example or something standard like a web-based book collection tool or smth.

Edit: Well that's pretty much the wrong question. I'm just wondering how one thinks about a typical RESTfull web thingy in functional terms.

Last edited by clowntable; 01-09-2013 at 01:18 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 01:13 PM
dave,

1. you'll have to work pretty hard to get the *compiler* to fail while compiling your code.

2. for understanding deep compiler behavior, there are few tools as useful as reading the generated assembly.


clown,

REST is just a way to have parts of your application call one another. i don't see how FP changes anything.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 01:42 PM
Quote:
Originally Posted by Shoe Lace
Arrays in C can almost be thought of as just pointers. When you do stuff like: foo[2] you are really just doing pointer arithmetic under the hood. The bracket notation is just syntactic sugar.

They are just a sequence of bytes lined up in a row. A character type takes up 1 byte so it's easy to see where it ends, it ends after 1 byte. No need for a \0.

A string needs a trailing \0 because it's a sequence of bytes of unknown length, also known as a char*. The only way a human can know that a string is finished is checking for \0.

Think about how you would implement strlen() by yourself. It would likely involve going through the array 1 character at a time until you hit \0, and now you know the length assuming you were incrementing a counter along the way.
I miss this stuff, lol.

Quote:
Due to how the stack works you may or may not segfault if you go out of bounds on an array. C has no auto-check on that, so it's up to you to not be a goofball. Results will vary. In the "broken" example you would likely segfault if you made the "broken" string a few dozen or a 100ish characters but it wouldn't be guaranteed, your chances would just go up.

Edit:

To be super clear (and maybe to check to make sure I'm right because I'm not 100% on this), the array living in main() is living in main's stack space. When you access an array outside of its bounds, you're actually climbing up in memory even though the stack can be thought of as growing downwards conceptually.

So when you read a higher than expected value you are climbing up (backtracking) up the stack until you reach another layer of memory reserved for your application. This is still ok because you own that memory space. You'll only crash if you read so many bytes that it places you outside the scope of your app, and then you'll segfault. Since we're dealing with pointers here I don't think it matters what type of data is contained there because a pointer is a pointer in the end, it's just pointing to something.

Is that right?
Yeah, this looks good. Memory layout and and what happens when you try to access outside are of course architecture-dependent (and where the underlying architecture is flexible enough to allow multiple layers of protection and/or multiple layout/calling-convention, it's also OS-dependent; and where OSes allow different calling conventions, part of the memory layout can even be calling-convention-dependent!) Seg-faults essentially come down to the processor/OS having determined that the process is doing something it's not allowed to do. Some architectures/OS are more strict and others are more loose. Also the ring-level matters - obviously at ring 0, there's no seg-fault, only memory corruption.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:04 PM
Quote:
Originally Posted by clowntable
Well that's pretty much the wrong question. I'm just wondering how one thinks about a typical RESTfull web thingy in functional terms.
Still not sure what you're asking. Are you asking how do we abstract state in a stateless language? Honestly I (and just about everyone else) cheat and use state because I don't think there are any production-quality functional/monadic databases that push state further down the chain but if you want to do web thingy without implicit state, you'd probably want to understand monads. Don't blame me when you want to pull your hair out though

Or are you maybe thinking how do you write a typical RESTful service with controllers and models in more functional languages? Generally speaking, how you deal with state without state in functional programming is that your program becomes a meta-program that describes how stateful computation can proceed. The compiler magically transforms your meta-program into a program that has the side effect of also executing the stateful computation your meta-program described. This cleanly separates state from your core invariant logic, because the stateful computation you're describing cannot be mixed with your pure functional program (it's a world within a world, just like in Matrix or Inception)
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:09 PM
The example may work better if you use dynamically allocated memory.

Code:
#include <stdio.h>
int main(int c, char **v)
{
    /* Stinking inability to use tab in this box */
    const int length = 4;
    char *string = malloc(length);
    for(int i = 0; i < length; ++i)
    {
        string[i] = 'a';
    }
    printf("String: '%s'\n", string);
    return 0;
}
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:12 PM
Quote:
Originally Posted by tyler_cracker
dave,

1. you'll have to work pretty hard to get the *compiler* to fail while compiling your code.
This. You have to think in terms of what's a theoretically valid input for the compiler that is nevertheless going to lead to problems for straightforward implementations. For a language with a complex type system (Scala, C++, etc), you attack the type system and because it's easily the most complicated required part to implement a language spec. For others, you have to try much harder and find the weak component (parser? preprocessor?) or bugs.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:14 PM
Quote:
Originally Posted by clowntable
I work with Prolog (thus Erlang seems like a decent candidate) and my main problem with it is the split between different "Prolog distributions". It's similar to Lisp in that regard I guess. Cummunity seems to be a bunch of "oldtimers" as well :P
There's also a bunch of proprietary Prologs which is a pretty big no-go for me. Stuff like Sicstus has a good share of the Prolog market I think.

Prolog I/O is also somewhat strange/feels unnatural imo. We use Prolog for the controller and Tomcat/JAVA/JS/HTML/CSS as the presentation and glue. It's based on a Postgresql database. It doesn't really use the much of the power of Prolog at all since we handle DB interaction via JAVA mostly.

A Prolog based framework would certainly be interesting. Maybe Datalog would be better but I don't know much about it other than having heard that it kind of solves the "code order matters" issue of Prolog.
I think Datomic is based on it?!
Something that might be of interest to you is Elixir. It's built on the Erlang VM with Ruby/Smalltalk-esque syntax. Going to be quite a bit of emphasis on web. http://elixir-lang.org/

It's still really young but the creator, Jose Valim, is a really hard worker and web tools are on the way.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:50 PM
Quote:
Originally Posted by Neil S
The example may work better if you use dynamically allocated memory.

Code:
#include <stdio.h>
int main(int c, char **v)
{
    /* Stinking inability to use tab in this box */
    const int length = 4;
    char *string = malloc(length);
    for(int i = 0; i < length; ++i)
    {
        string[i] = 'a';
    }
    printf("String: '%s'\n", string);
    return 0;
}
You're allocating memory on the heap here. You are leaking memory by not freeing "string" before exiting. You don't want to poor Dave to pickup bad habits!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 02:55 PM
Nice one.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 03:23 PM
Elixir is pretty interesting indeed. Thanks for reminding me of its existance.

candybar: Your second paragraph helped quite a bit. I tihnk I'll browse the CouchDB source as that might have some answers. Basically I think I don't quite get functional+data storage.

Basically the way I envision it is that you have some base data and a chain of functions that is applied to it. I guess you can kind of garbage collect the base data or something?
Like you'd have x = 42 then x = inc(x) iirc shadowing means you can give it the same name so basically I'm wondering how you handle shadowed data I guess.

Are there any good non-language specific functional source. I.e. something like "fundamentals of functional programming" or "thinking functional" or smth.?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 04:51 PM
LISP. If I recall correctly, LISP started out as just the notation in a CS paper, that someone turned around and made into an actual programming language.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 07:04 PM
Quote:
Originally Posted by clowntable
Elixir is pretty interesting indeed. Thanks for reminding me of its existance.

candybar: Your second paragraph helped quite a bit. I tihnk I'll browse the CouchDB source as that might have some answers. Basically I think I don't quite get functional+data storage.
As for how to deal with mutable state in Erlang:

http://james-iry.blogspot.com/2009/0...all-about.html

Erlang is somewhat on its own in terms of how it deals with state though and I'd argue that Actors are more conceptually pure message-passing OO than anything to do with functional programming. In practice, most functional programmers cheat and use implicit state like everyone else. Some people's idea of functional programming also has little to do with referential transparency and simply functions as first-class objects or closures, which are stateful. I'm half-way between that camp (say, Ruby/Lisp people) and monadic camp (Haskell), in the Scala/ML land where we acknowledge the usefulness of pure functional abstractions as well as the importance of allowing people to get stuff done.

Quote:
Basically the way I envision it is that you have some base data and a chain of functions that is applied to it. I guess you can kind of garbage collect the base data or something?
Like you'd have x = 42 then x = inc(x) iirc shadowing means you can give it the same name so basically I'm wondering how you handle shadowed data I guess.
If this is sufficient, you have no need for state. If you passed an original reference to x to somewhere else and he still gets the original x, even after you've done this, you can just single-assignment transform this to be x = 42 and x1 = inc(x) and statically rename x to x1 where appropriate. If the other guy needs to access x, whatever you set it to and he can't know beforehand whether it's going to be x or x1, then you have mutable state.

The best way to understand how this works is probably a tutorial on monads in a language you're already familiar with. If you understand monads, it's going to open eyes because it formalizes and unifies many different things you're taking for granted. Options are monads. Lists are monads. Promises/futures are monads. Parsers are monads. Continuations are monads.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 07:31 PM
Quote:
Originally Posted by daveT
That's the issue with programming languages: you choose one and go with it, but you are fundamentally part of some "club" whether you want to be part of it or not. Unfortunately, the Clojure and Lisp community is all talk and no action. Much ink is spilled on how great Lisp and Clojure is, openly bashing lesser languages, but there is no tangible proof to back it all up. PHP / Ruby / Python / Java sucks? Look at all the cool things they are doing.
A language that ranks too high in prestige/snob-appeal/idealism relative to its real-world usefulness is going to attract too many people who want to use it to feel better about themselves and cherish their minority status, as opposed to people who want to get things done. This leads to an ecosystem that is oriented towards maintaining its prestige, as opposed to being useful to allow everyone else to get things done. This is a bit unfair, because there are tons of Lisp programmers who don't fit this description, but Lisp in particular has a history of attracting uncompromising idealists, language snobs and others of elitist mindset.

Expressiveness matters for adoption and productivity but abstract cleanness and nonbrokenness of the language that purists care about usually only become relevant for extremely large applications which these clean languages ultimately never get used for, in part because the community refuses to compromise.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 09:43 PM
Quote:
Originally Posted by clowntable
Functional programmers:
How would one go about mixing FP and REST? I've only really thought of REST in an OO context.

Feel free to use any example or something standard like a web-based book collection tool or smth.

Edit: Well that's pretty much the wrong question. I'm just wondering how one thinks about a typical RESTfull web thingy in functional terms.
REST isn't really tied to a specific programming paradigm. It's just that REST is almost always used in the context of HTTP and HTTP apps are usually web apps which in turn are modeled using OO languages and frameworks quite often.

While CouchDB would be a good study, I think something like WebMachine or Cowboy would be a better one to look at first. If I recall correctly, CouchDB uses WebMachine to handle HTTP requests. Starting at WebMachine and working into CouchDB might be a good idea.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 09:44 PM
Quote:
Originally Posted by candybar
A language that ranks too high in prestige/snob-appeal/idealism relative to its real-world usefulness is going to attract too many people who want to use it to feel better about themselves and cherish their minority status, as opposed to people who want to get things done. This leads to an ecosystem that is oriented towards maintaining its prestige, as opposed to being useful to allow everyone else to get things done. This is a bit unfair, because there are tons of Lisp programmers who don't fit this description, but Lisp in particular has a history of attracting uncompromising idealists, language snobs and others of elitist mindset.

Expressiveness matters for adoption and productivity but abstract cleanness and nonbrokenness of the language that purists care about usually only become relevant for extremely large applications which these clean languages ultimately never get used for, in part because the community refuses to compromise.
+1 hundred thousand trillion zillion
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 10:04 PM
Quote:
Originally Posted by daveT
That's the issue with programming languages: you choose one and go with it, but you are fundamentally part of some "club" whether you want to be part of it or not. Unfortunately, the Clojure and Lisp community is all talk and no action. Much ink is spilled on how great Lisp and Clojure is, openly bashing lesser languages, but there is no tangible proof to back it all up. PHP / Ruby / Python / Java sucks? Look at all the cool things they are doing.
Quote:
Originally Posted by candybar
A language that ranks too high in prestige/snob-appeal/idealism relative to its real-world usefulness is going to attract too many people who want to use it to feel better about themselves and cherish their minority status, as opposed to people who want to get things done. This leads to an ecosystem that is oriented towards maintaining its prestige, as opposed to being useful to allow everyone else to get things done. This is a bit unfair, because there are tons of Lisp programmers who don't fit this description, but Lisp in particular has a history of attracting uncompromising idealists, language snobs and others of elitist mindset.

Expressiveness matters for adoption and productivity but abstract cleanness and nonbrokenness of the language that purists care about usually only become relevant for extremely large applications which these clean languages ultimately never get used for, in part because the community refuses to compromise.
Strong observations from both of you.

This is precisely what I was alluding to with my "boys club" question. It's also one of the reasons that I like the 2p2 Programming forum -- an eclectic mix of backgrounds keeps this in check.

The issue seems somewhat analogous to inbreeding, or perhaps water stagnation. It's a problem that perpetuates itself because it needs outside influence to improve, and yet the greatest effect of the problem is that it repels outsiders.

Maybe this is how programming languages die?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 11:00 PM
I started a new project a few days ago, it's a poker web app. I'm writing the thing in python/django and open to learning some javascript if it's convenient. The idea is basicially that you can play heads up no limit holdem, except it will be like web board style, ie there will be no clock. You just check in, see the hands you need to act on, and then later come back, refresh, and repeat. Here's a screenshot of what I have in mind.
So new actions go to the top and push old actions down. In the future I want to have multiple columns, each column representing a different table so that you can multitable.

The problem I'm having right now is that in Django, it's the url request that sets off the server side code, so what's happening is that if you refresh the page or click back and resend data you can give yourself a new hand or flop or w/e. I'd love to hear any ideas about that or any suggestions in general.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-09-2013 , 11:20 PM
Quote:
Originally Posted by WeAreSamurai
The problem I'm having right now is that in Django, it's the url request that sets off the server side code, so what's happening is that if you refresh the page or click back and resend data you can give yourself a new hand or flop or w/e. I'd love to hear any ideas about that or any suggestions in general.
so the url presumably has some ID representing the hand number, or an identifier that represents a collection of multi-tabled hands.

in any case, you need to remember (ie, store in a database) the current state of all the hands. so that way you know if the action "generate flop" has already occured. if it has, instead of performing it again, you just redisplay the saved flop and prompt again for the required user action (ie, bet, check, etc).

a hand is in a state. that state has a view. one state transitions to another state depending on user actions. that's all it is from a high level.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-10-2013 , 03:02 AM
Hi, clowntable, I'm confused by what you are asking, so I'll give you a long-tail of what I am thinking and hopefully I'll hit on something useful here.

First of all, I'm confused that you are asking about state irt to HTTP, since HTTP itself is a stateless system.

Second, don't conflate statelessness with timelessness. Functional programming does not deny time or state exist: it is only an approach to controlling state and time. Let me give you an example that may help you out. Suppose you're best friend is a cat-woman, and she would like to keep a record of all the cats she ever owned. Suppose she was an excellent ledger person who kept really good notes and thankfully, she isn't the 100+ cats person but only own at most 10, so you decide that the best way to track this is create a list of the names and you start at January of 2000:

Jan2000 = [bobby, karl, george, bunny]

And then you move to February2000. Turns out poor karl died:

Feb2000 = [bobby, george, bunny]

So, what would happen if you did Jan2000.append(mooCow)?

Well, Jan2000 would not be "changed" and every subsequent call to Jan2000 would return the original list. You would have to go completely out of your way to simply rename Jan2000 to an entirely different value. This is not quite the truth, there are ways to completely change Jan2000, but I'm not going to do into that.

This is the foundation of functional "stateless" thinking. If you were to do this in a "stateful" system, then you'd have:

cats = [bobby, karl, george, bunny]

cats = [bobby, george, bunny]

So, now that every time you call the cats list, you "destroyed" the earlier state and now cats is specifically an object representing the current state of cats. This is stupid example, but that is sort of the whole point of it all. You may not be able to pick February 3, 2012 from your data because you decided to keep it all stateful so you effectively lost all of the prior data.

A slightly more abstract consequence of all of this is posed in SICP, where they say that time and state in FP-land is more akin to special relativity. For a quick minute explanation, check out this youtube video: http://www.youtube.com/watch?v=ajhFNcUTJI0

Clojure + Ring + Compojure interacts with the webserver with all the fun stuff you would get with any HTTP connection system: GET, POST, DELETE, PUT.

I've copy/pasted this piece from Clojure Programming:

Code:
{: remote-addr "127.0.0.1", 
:scheme :http, 
:request-method :get, 
:query-string "q = Acme", 
:content-type nil, 
:uri "/ accounts", 
:server-name "company.com", 
:content-length nil, 
:server-port 8080, 
:body #< ByteArrayInputStream java.io.ByteArrayInputStream@ 604fd0e9#>, 
:headers 
{" user-agent" "Mozilla/ 5.0 (Macintosh; Intel Mac OS X 10.6) 
Firefox/ 8.0.1", 
"accept-charset" 
"ISO-8859-1, utf-8; q = 0.7,*; q = 0.7", 
"accept" 
"text/ html, application/ xhtml + xml, application/ xml; q = 0.9,*/*; q = 0.8", "accept-encoding" "gzip, deflate", 
"accept-language" 
"en-us, en; q = 0.5", 
"connection" "keep-alive"}}
But that's a lot of crap that I'm sure you wouldn't want to deal with, but maybe it makes sense to you? That is how Ring works, but perhaps that is way too much to bother with, so Compojure comes with a macro called defroutes, which looks like this:

Code:
(defroutes
 (GET "/" (home-page))
 (POST "/" (args-to-db))
 (GET "/another-page" (another-page))
 (route/not-found (four-oh-four)))
And I've never uses the DELETE or PUT parameters, so I'm not sure if the following is correct:

Code:
(defroutes 
 (GET "/" (home-page))
 (POST "/" (args-to-db))
 (GET "/another-page" (another-page))
 (DELETE "/" (arg-to-db))
 (PUT "/" (args-to-db))
 (route/not-found (four-oh-four)))
So, basically, I don't have any code-level mutation that I've worked with. I simply mutate values in the database. Although it does look like I am mutating, I'm actually not. If you recall the effect of building up a resume from my demo site, I basically have a bunch of local-bound values that point to the database, but if nothing in the database changes, then the post-parameters are never executed and there is no subsequent calls to the database or page reloads.

As far as Datomic goes, I think it works by not using CRUD, but by using CRU AD (Create, Read, Update, Append, Delete), which allows you to create a new object by appending a new value to an old value and not destroying the history of the database, so you can easily recover what happened last Tuesday at 3:00.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-10-2013 , 03:11 AM
Hey, xhad. Code Academy is not on the front page of HN and everyone is talking up how great they are.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
01-10-2013 , 03:50 AM
Quote:
Originally Posted by Shoe Lace
Arrays in C can almost be thought of as just pointers. When you do stuff like: foo[2] you are really just doing pointer arithmetic under the hood. The bracket notation is just syntactic sugar.

They are just a sequence of bytes lined up in a row. A character type takes up 1 byte so it's easy to see where it ends, it ends after 1 byte. No need for a \0.

A string needs a trailing \0 because it's a sequence of bytes of unknown length, also known as a char*. The only way a human can know that a string is finished is checking for \0.

Think about how you would implement strlen() by yourself. It would likely involve going through the array 1 character at a time until you hit \0, and now you know the length assuming you were incrementing a counter along the way.

Due to how the stack works you may or may not segfault if you go out of bounds on an array. C has no auto-check on that, so it's up to you to not be a goofball. Results will vary. In the "broken" example you would likely segfault if you made the "broken" string a few dozen or a 100ish characters but it wouldn't be guaranteed, your chances would just go up.

Edit:

To be super clear (and maybe to check to make sure I'm right because I'm not 100% on this), the array living in main() is living in main's stack space. When you access an array outside of its bounds, you're actually climbing up in memory even though the stack can be thought of as growing downwards conceptually.

So when you read a higher than expected value you are climbing up (backtracking) up the stack until you reach another layer of memory reserved for your application. This is still ok because you own that memory space. You'll only crash if you read so many bytes that it places you outside the scope of your app, and then you'll segfault. Since we're dealing with pointers here I don't think it matters what type of data is contained there because a pointer is a pointer in the end, it's just pointing to something.

Is that right?
Anyone have anything to add to this?

I thought this exercise was interesting: http://c.learncodethehardway.org/book/ex8.html
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m