프로그래밍/C2014.06.05 09:17

for (i=0; i < size && iterator->next != NULL; i++, iterator=iterator->next)


for 문 조건처리에서는 위와 같이 &&나 ||를 써줘야 한다. 만약 대신에 ','를 쓴다면 


for (i=0; i < size, iterator->next != NULL; i++, iterator=iterator->next)


앞의 조건, i < size는 그냥 무시가 되어 버리니 조심하자.  하지만 처리 부분에서는 ','를 써서 처리하면 된다.

신고
Posted by code cat
프로그래밍/C2014.06.02 16:29

strerror

#include <stdio.h>

#include <string.h>


void main()

{

  FILE *fp;

  if ((fp = fopen("data.txt", "r")) == NULL) {

    fprintf(stderr, "ERROR: %s\n", strerror(errno));

    exit(1);

  }

  exit(0);

}


strerror는 errno를 받아서 실패한 원인에 대한 메세지를 리턴한다.


그런데 perror는 더 편리하다.

perror

#include <stdio.h>


void main()

{

  FILE *fp;

  if ((fp = fopen("data.txt", "r")) == NULL) {

    perror("ERROR");  // 오류가 발생했을 때 오류 출력시에 앞에 붙는 PREFIX를 인자로 받는다.

    exit(1);

  }

  exit(0);

}


신고
Posted by code cat
프로그래밍/C2014.05.29 11:22

출처: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc

In this question, someone suggested in a comment that I should not cast the results of malloci.e:

int *sieve = malloc(sizeof(int)*length);

rather than:

int *sieve = (int *)malloc(sizeof(int)*length);

Why would this be the case?


No; you don't cast the result, since:

  • It is unnecessary, as void * is automatically and safely promoted to any other pointer type in this case.
  • It can hide an error, if you forgot to include <stdlib.h>. This can cause crashes, in the worst case.
  • It adds clutter to the code, casts are not very easy to read (especially if the pointer type is long).
  • It makes you repeat yourself, which is generally bad.

As a clarification, note that I said "you don't cast", not "you don't need to cast". In my opinion, it's a failure to include the cast, even if you got it right. There are simply no benefits to doing it, but a bunch of potential risks, and including the cast indicates that you don't know about the risks.

Also note, as commentators point out, that the above changes for straight C, not C++. I very firmly believe in C and C++ as separate languages.

To add further, your code needlessly repeats the type information (int) which can cause errors. It's better to dereference the pointer being used to store the return value, to "lock" the two together:

int *sieve = malloc(length * sizeof *sieve);

This also moves the length to the front for increased visibility, and drops the redundant parentheses with sizeof; they are only needed when the argument is a type name. Many people seem to not know (or ignore) this, which makes their code more verbose. Remember: sizeof is not a function! :)


@sirgeorge - without the prototype/decl (in stdlib.h), a C compiler might/will assume that malloc returns an int. Then the compiler generates code for the call in question as if it is getting an int. Then, say, you are compiling for a platform where pointers and ints do not have the same size, and you cast the returning int into a pointer. Bad juju. And the compiler, upon seeing the casting, won't give you a warning in this case. But if you don't cast it, then the compiler will complain abou the int-to-ptr assignment (and you will be able to detect the missing include for stdlib.h) –  luis.espinal Mar 14 '12 at 19:28 

신고

'프로그래밍 > C' 카테고리의 다른 글

for 문 multiple 조건 & 처리  (0) 2014.06.05
strerror 사용법, perror 사용법  (0) 2014.06.02
malloc 를 캐스팅 하지 말자.  (0) 2014.05.29
strtok에 NULL을 전달하는 이유  (0) 2014.05.29
함수포인터 & typdef를 이용한 함수포인터  (0) 2014.05.07
ternary operator  (0) 2014.04.13
Posted by code cat
프로그래밍/C2014.05.29 09:32

strtok를 쓸 때, 왜 두번째 콜에서 NULL을 넘겨줄까? 그냥 그러려다 찾아보았다.


char str[] = "Hello World. How are you?";
        char delim[] = " ";
        char *ptr;

ptr = strtok(str, delim);
        printf("%s\n", ptr);
        while(ptr = strtok(NULL, delim))
            printf("%s\n", ptr);


다음은 strtok.c 의 내용이다.(glibc 2.19버전)


18 #include <string.h>
19 
20 
21 static char *olds;
22 
23 #undef strtok
24 
25 /* Parse S into tokens separated by characters in DELIM.
26  If S is NULL, the last string strtok() was called with is
27  used. For example:
28  char s[] = "-abc-=-def";
29  x = strtok(s, "-"); // x = "abc"
30  x = strtok(NULL, "-="); // x = "def"
31  x = strtok(NULL, "="); // x = NULL
32  // s = "abc\0=-def\0"
33 */
34 char *
36  char *s;
37  const char *delim;
38 {
39  char *token;
40 
41  if (s == NULL)
42  s = olds;
43 
44  /* Scan leading delimiters. */
45  s += strspn (s, delim);
46  if (*s == '\0')
47  {
48  olds = s;
49  return NULL;
50  }
51 
52  /* Find the end of the token. */
53  token = s;
54  s = strpbrk (token, delim);
55  if (s == NULL)
56  /* This token finishes the string. */
57  olds = __rawmemchr (token, '\0');
58  else
59  {
60  /* Terminate the token and make OLDS point past it. */
61  *s = '\0';
62  olds = s + 1;
63  }
64  return token;
65 }


41라인을 보면 NULL일 경우, static 변수 old로 대체한다. 아! 그래서 NULL을 써서 이어서 파싱이 되게 하는구나.  그리고 static변수라... 쓰레드 사용시에 문제가 있을 거 같다.

추가로 찾아본 내용을 보니,(http://ogoons.tistory.com/m/post/70) 다음과 같은 주의사항이 있다.


1. strtok()의 사용 후, 원본 문자열의 데이터를 보장할 수 없다.
2. visual studio 상위 버전에 문제가 있을 수 있다.
3. strtok()은 내부적으로 문자열 분리를 위해 static변수를 놓고 정적공유를 함으로 , thread-safe하지 않다.(음 역시)


따라서 위의 상황들을 개선한 strtok_s()를 쓰길 권장한다고 한다.


char str[] = "Hello World Good, Morning Sunshine";

char delim[] = " ,";

char *ptr;

char *context = NULL;

ptr = strtok_s(str, delim, &context);

printf("%s\n", ptr);

while(ptr = strtok_s(NULL, delim, &context))

printf("%s\n", ptr);


신고
Posted by code cat
프로그래밍/C2014.05.07 15:33


if 0로 묶여 있는 부분은 보통의 함수포인터를 부르는 방식이다.
하지만 이는 복잡해 보이고 혼란을 줄 수 있는 모양일 수 있다.  따라서 코드를 깔끔하게 보이기 위해 else로 묶여있는 부분을 보면 typedef를 통한 함수포인터 사용을 볼 수 있다.


typedef에 대한 부분이 혼란스러우면 아래와 같이 이해하면 좋다(출처:https://kldp.org/node/119822)

typedef를 빼면 변수 선언 붙이면 타입 선언이라고 이해하시면 편합니다.

unsigned int u32; // u32는 unsigned int 타입의 변수
typedef unsigned int u32; // u32는 unsigned int 타입

int (*func)(int, int); // func는 (int, int)를 받고 int를 리턴하는 함수에 대한 포인터 타입의 변수
typedef int (*func)(int, int); // func는 (int, int)를 받고 int를 리턴하는 함수에 대한 포인터 타입


신고
Posted by code cat

1. Account settings -> Composition and Addressing 에서 "Compose message in HTML format"을 uncheck


2. Preferences -> Composition -> Send Options -> Text Format에서 "Convert the message to plain text"로 변환


신고
Posted by code cat
프로그래밍/python2014.04.24 17:23

참조: 열혈강의 파이썬, 이강성 저

 

Class 는 하나의 이름 공간이며 기본적으로 다음과 같다.


위에서 상속도 나와있는데 OOP를 아는 사람이라면 쉽게 이해가 가능하다.

class Name:  #header
  pass          #body

class는 위와 같이 header와 body의 형태이며, header의 경우, :를 붙인다.  pass는 아무 일도 하지 않고 자리를 채우는 명령문이다.

 

method의 정의는 다음과 같다.

class MyClass:
  def set(self, v):
    self.value = v
  def put(self):
    print self.value

method를 정의하기 위해서는 def를 사용하며, 첫 인수로 self를 사용한다.  이는 자바에서 쓰는 'this'와 유사하다고 보면 된다.(자기자신의 인스턴스 객체를 가리킨다)

 

method 호출은 두가지 방법이 있다.

1. Unbound Class Method

>>> MyClass.set(c, 'egg')
>>> MyClass.put(c)

egg

2. Bound Instance Method

>>> c = MyClass()

>>> c.set('egg')

>>> c.put()

egg

 

class 내부에서의 method 호출은 self. 를 이용하여야 한다.

신고

'프로그래밍 > python' 카테고리의 다른 글

[python] Class  (0) 2014.04.24
Posted by code cat
프로그래밍/C2014.04.13 20:27

출처: http://en.wikipedia.org/wiki/%3F:

GNU확장은 다음과 같이 값을 프로세싱을 한번 이상 할 경우, 문제가 되는 경우를 대비해 다음과 같이 operand를 스킵할 수 있게 한다.


a = x ? : y;


상기 라인은 아래와 같다.

a = x ? x : y;


만일 x가 expression이라면, 한번만 프로세싱된다.


신고
Posted by code cat
안드로이드/포팅2014.04.13 18:36

[    3.11328] init: skipping insecure file '/default.prop'
[    3.133259] init: skipping insecure file '/init.rc'

라는 에러 메세지가 나오면서 부팅이 안되면, 이는 다음과 같이 젤리빈(이상버전 동일?)에서 다음과 같이 파일 스탯을 참조하여, owner외에 writable 못하게 막아놓았기 때문이다.

143    char *data;
144    int sz;
145    int fd;
146    struct stat sb;
147
148    data = 0;
149    fd = open(fn, O_RDONLY);
150    if(fd < 0) return 0;
151
152    // for security reasons, disallow world-writable
153    // or group-writable files
154    if (fstat(fd, &sb) < 0) {
155        ERROR("fstat failed for '%s'\n", fn);
156        goto oops;
157    }
158    if ((sb.st_mode & (S_IWGRP | S_IWOTH)) != 0) {


그럼 간단히, 644 혹은, 655 정도로 파일 퍼미션을 바꿔주면 된다.

신고
Posted by code cat
리눅스/커널2014.04.08 15:10

dentry cache hash table size 지정은,

fs/dcache.c에서 alloc_large_system_hash를 통해서 된다. 그전에 dhash_entries는 kernel cmdline에서 지정하여 원하는 값을 패스 할 수 있다.

2965static void __init dcache_init(void)
2966{
2967        int loop;
2968
2969        /* 
2970         * A constructor could be added for stable state like the lists,
2971         * but it is probably not worth it because of the cache nature
2972         * of the dcache. 
2973         */
2974        dentry_cache = KMEM_CACHE(dentry,
2975                SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD);
2976
2977        /* Hash may have been set up in dcache_init_early */
2978        if (!hashdist)
2979                return;
2980
2981        dentry_hashtable =
2982                alloc_large_system_hash("Dentry cache",
2983                                        sizeof(struct hlist_bl_head),
2984                                        dhash_entries,
2985                                        13,
2986                                        0,
2987                                        &d_hash_shift,
2988                                        &d_hash_mask,
2989                                        0);
2990
2991        for (loop = 0; loop < (1 << d_hash_shift); loop++)
2992                INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
2993}


그리고 만약 dhash_entries값이 0이면(전역비초기화 변수 이므로 0으로 되어 bss영역에 있을 것이다) 5395라인 하위로 타고 들어가, nr_kernel_pages에 기반을 둔 2의 배수를 설정하고 기타 log2작업(아 이건 나중에 보자...)을 통해 hash table size를 출력한다.

5381void *__init alloc_large_system_hash(const char *tablename,
5382                                     unsigned long bucketsize,
5383                                     unsigned long numentries,
5384                                     int scale,
5385                                     int flags,
5386                                     unsigned int *_hash_shift,
5387                                     unsigned int *_hash_mask,
5388                                     unsigned long limit)
5389{
5390        unsigned long long max = limit;
5391        unsigned long log2qty, size;
5392        void *table = NULL;
5393
5394        /* allow the kernel cmdline to have a say */
5395        if (!numentries) {
5396                /* round applicable memory size up to nearest megabyte */
5397                numentries = nr_kernel_pages;
5398                numentries += (1UL << (20 - PAGE_SHIFT)) - 1;
5399                numentries >>= 20 - PAGE_SHIFT;
5400                numentries <<= 20 - PAGE_SHIFT;
5401
5402                /* limit to 1 bucket per 2^scale bytes of low memory */
5403                if (scale > PAGE_SHIFT)
5404                        numentries >>= (scale - PAGE_SHIFT);
5405                else
5406                        numentries <<= (PAGE_SHIFT - scale);
5407
5408                /* Make sure we've got at least a 0-order allocation.. */
5409                if (unlikely(flags & HASH_SMALL)) {
5410                        /* Makes no sense without HASH_EARLY */
5411                        WARN_ON(!(flags & HASH_EARLY));
5412                        if (!(numentries >> *_hash_shift)) {
5413                                numentries = 1UL << *_hash_shift;
5414                                BUG_ON(!numentries);
5415                        }
5416                } else if (unlikely((numentries * bucketsize) < PAGE_SIZE))
5417                        numentries = PAGE_SIZE / bucketsize;
5418        }
5419        numentries = roundup_pow_of_two(numentries);
5420
5421        /* limit allocation size to 1/16 total memory by default */
5422        if (max == 0) {
5423                max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
5424                do_div(max, bucketsize);
5425        }
5426
5427        if (numentries > max)
5428                numentries = max;
5429
5430        log2qty = ilog2(numentries);
5431
5432        do {
5433                size = bucketsize << log2qty;
5434                if (flags & HASH_EARLY)
5435                        table = alloc_bootmem_nopanic(size);
5436                else if (hashdist)
5437                        table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL);
5438                else {
5439                        /*
5440                         * If bucketsize is not a power-of-two, we may free
5441                         * some pages at the end of hash table which
5442                         * alloc_pages_exact() automatically does
5443                         */
5444                        if (get_order(size) < MAX_ORDER) {
5445                                table = alloc_pages_exact(size, GFP_ATOMIC);
5446                                kmemleak_alloc(table, size, 1, GFP_ATOMIC);
5447                        }
5448                }
5449        } while (!table && size > PAGE_SIZE && --log2qty);
5450
5451        if (!table)
5452                panic("Failed to allocate %s hash table\n", tablename);
5453
5454        printk(KERN_INFO "%s hash table entries: %ld (order: %d, %lu bytes)\n",
5455               tablename,
5456               (1UL << log2qty),
5457               ilog2(size) - PAGE_SHIFT,
5458               size);
5459
5460        if (_hash_shift)
5461                *_hash_shift = log2qty;
5462        if (_hash_mask)
5463                *_hash_mask = (1 << log2qty) - 1;
5464
5465        return table;
5466}


신고

'리눅스 > 커널' 카테고리의 다른 글

커널 디버깅 방법  (0) 2014.09.19
syslog LOCAL7  (0) 2014.08.28
Dentry cache hash table 사이즈  (0) 2014.04.08
Memory 정보 출력되는 곳  (0) 2014.04.07
driver 초기화 시에 쓰이는 module_init  (0) 2014.04.04
Machine 이름 바꾸기  (0) 2014.04.03
Posted by code cat

티스토리 툴바