Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 75

0
votes
answers
18 views
+10

boost ::線程函數執行

1

如何使用boost ::線程執行每個線程在其自己的內存空間中執行的函數。所以當我在函數中分配一個新變量時,它只能作爲執行線程中的一個實例存在。boost ::線程函數執行

只是爲了澄清我想使用boost :: thread生成執行相同方法的線程,但我不想使用鎖或信號燈,我只是希望它在單獨的空間中執行。

沙发
0
4

您在線程函數內分配的任何內容對於該函數而言都是本地的,只要它們未聲明爲static即可。正常編寫你的代碼(避免static局部變量),你會沒事的。

板凳
0
3

如果您需要創建一個完全在其自己的地址空間內運行的線程,那麼您要做的是創建一個進程,而不是一個線程。定義線程是在父進程的相同地址空間內運行的執行點。

如果您確實需要創建線程(即線程之間共享內存和其他資源),但您還需要一部分專用於特定線程的內存,那麼您有幾個選項: 1)as ildjarn建議,讓線程程序分配本地(或動態內存)並編寫代碼,以便每個線程使用它自己分配的內存。 2)看看TLS(線程本地存儲)。它是一個API,允許您創建專用於特定線程的「全局」變量。 C++的一些變體也有內置關鍵字來聲明使用TLS的變量。

請注意,在上述選項中,您不會自動隔離線程無法破壞其他線程內存的情況。獲得此隔離的唯一方法是產生多個進程(或切換到.NET語言之一併實例化在同一進程中運行的多個AppDomain)。

0
votes
answers
18 views
+10

在C++的特定範圍內生成隨機均勻可分的數字?

-1

我正在爲五年級的Flashcard計劃來練習他們的數學技能。無論何時他們到達程序的分割部分,它都不會生成均勻分割的數字。我已經生成了兩個數字,像這樣:在C++的特定範圍內生成隨機均勻可分的數字?

int divisor_one = 1+rand()%5 * 2; 
    int divisor_two = 1+rand()%5 * 2; 

我想通過乘以由兩個,但只給出偶數,但我錯了。它會生成一個5,如下所示。

******************************** 
      Division Flashcards 
    ******************************** 
        3 
        5 
       _____ 

顯然,這兩個數字並不能被整除。我怎樣才能生成隨機均勻分割數字?

+5

好像你將隨機數乘以2,然後加1.'(1 + rand()%5)* 2;'可能會更好。 –

+0

這確實使它只產生偶數,但它不會使它們均勻**可分**。 –

+0

'>>但它並不能使它們均勻分割,那麼什麼是可以整除的數字呢? –

沙发
0
6

這是我腦子裏想的:

int divisor_one = 1+rand()%5 * 2; 
int result = 1+rand()%5 * 2; 
int divsor_two = divisor_one * result; 

這樣,你要確保結果始終是一個甚至產品的任何因素都。

1
votes
answers
16 views
+10

Why is f(i = -1, i = -1) undefined behavior?

I was reading about order of evaluation violations, and they give an example that puzzles me.

1) If a side effect on a scalar object is un-sequenced relative to another side effect on the same scalar object, the behavior is undefined.

// snip
f(i = -1, i = -1); // undefined behavior

In this context, i is a scalar object, which apparently means

Arithmetic types (3.9.1), enumeration types, pointer types, pointer to member types (3.9.2), std::nullptr_t, and cv-qualified versions of these types (3.9.3) are collectively called scalar types.

I don’t see how the statement is ambiguous in that case. It seems to me that regardless of if the first or second argument is evaluated first, i ends up as -1, and both arguments are also -1.

Can someone please clarify?


UPDATE

I really appreciate all the discussion. So far, I like @harmic’s answer a lot since it exposes the pitfalls and intricacies of defining this statement in spite of how straight forward it looks at first glance. @acheong87 points out some issues that come up when using references, but I think that's orthogonal to the unsequenced side effects aspect of this question.


SUMMARY

Since this question got a ton of attention, I will summarize the main points/answers. First, allow me a small digression to point out that "why" can have closely related yet subtly different meanings, namely "for what cause", "for what reason", and "for what purpose". I will group the answers by which of those meanings of "why" they addressed.

for what cause

The main answer here comes from Paul Draper, with Martin J contributing a similar but not as extensive answer. Paul Draper's answer boils down to

It is undefined behavior because it is not defined what the behavior is.

The answer is overall very good in terms of explaining what the C++ standard says. It also addresses some related cases of UB such as f(++i, ++i); and f(i=1, i=-1);. In the first of the related cases, it's not clear if the first argument should be i+1 and the second i+2 or vice versa; in the second, it's not clear if i should be 1 or -1 after the function call. Both of these cases are UB because they fall under the following rule:

If a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined.

Therefore, f(i=-1, i=-1) is also UB since it falls under the same rule, despite that the intention of the programmer is (IMHO) obvious and unambiguous.

Paul Draper also makes it explicit in his conclusion that

Could it have been defined behavior? Yes. Was it defined? No.

which brings us to the question of "for what reason/purpose was f(i=-1, i=-1) left as undefined behavior?"

for what reason / purpose

Although there are some oversights (maybe careless) in the C++ standard, many omissions are well-reasoned and serve a specific purpose. Although I am aware that the purpose is often either "make the compiler-writer's job easier", or "faster code", I was mainly interested to know if there is a good reason leave f(i=-1, i=-1) as UB.

harmic and supercat provide the main answers that provide a reason for the UB. Harmic points out that an optimizing compiler that might break up the ostensibly atomic assignment operations into multiple machine instructions, and that it might further interleave those instructions for optimal speed. This could lead to some very surprising results: i ends up as -2 in his scenario! Thus, harmic demonstrates how assigning the same value to a variable more than once can have ill effects if the operations are unsequenced.

supercat provides a related exposition of the pitfalls of trying to get f(i=-1, i=-1) to do what it looks like it ought to do. He points out that on some architectures, there are hard restrictions against multiple simultaneous writes to the same memory address. A compiler could have a hard time catching this if we were dealing with something less trivial than f(i=-1, i=-1).

davidf also provides an example of interleaving instructions very similar to harmic's.

Although each of harmic's, supercat's and davidf' examples are somewhat contrived, taken together they still serve to provide a tangible reason why f(i=-1, i=-1) should be undefined behavior.

I accepted harmic's answer because it did the best job of addressing all meanings of why, even though Paul Draper's answer addressed the "for what cause" portion better.

other answers

JohnB points out that if we consider overloaded assignment operators (instead of just plain scalars), then we can run into trouble as well.

沙发
+10

Actually, there's a reason not to depend on the fact that compiler will check that i is assigned with the same value twice, so that it's possible to replace it with single assignment. What if we have some expressions?

void g(int a, int b, int c, int n) {
    int i;
    // hey, compiler has to prove Fermat's theorem now!
    f(i = 1, i = (ipow(a, n) + ipow(b, n) == ipow(c, n)));
}
0
votes
answers
19 views
+10

爲什麼「extern int&c;」工作正常嗎?

6

在C++中,引用變量必須被初始化。 int&a; //錯誤爲什麼「extern int&c;」工作正常嗎?

static int &b; // Error 

extern int &c; // No error 

爲什麼編譯器沒有給出extern符引用錯誤?

+2

因爲初始化被迫在外部定義中發生。 – user0042

+3

'extern'位告訴編譯器'c'被聲明/定義在其他地方 –

+4

@rsp extern int&c;不是一個參考的定義。這只是一個沒有定義的聲明。 –

沙发
0
12

extern關鍵字是編譯器的指令,您現在正在聲明一個將在鏈接期間從另一個目標文件中獲取的符號。 初始化被預期發生在實際符號被定義的地方。

如果您在編譯文件b.c到B.O編譯器將離開符號bar空與

int foo; 
int &bar = foo; 

的交流轉換器文件,並

extern int &bar; 

一個b.c文件。當鏈接程序,鏈接器將需要找到出口符號bar在AO並再與bar從AO

更換空白符號博如果連接器無法找到所需的符號隨時隨地鏈接對象文件 - 將發佈鏈接器錯誤(不是編譯器錯誤)。

板凳
0
5

爲什麼編譯器不提供extern參考的錯誤?

因爲extern int &c;不是一個定義,而僅僅是聲明。它通知編譯器c將在程序中的其他位置定義。

cppreference page on "storage class specifiers"解釋了在這種情況下extern的含義。

地板
0
5

語言規範明確地說

8.3.2參考
[...]一個引用的聲明應包含在報關的時候包含了除一個初始化(8.6.3)一個明確的extern說明符(7.1.1),是類定義中的類成員(9.2)聲明,或是參數或返回類型(8.3.5)的聲明 ;見3.1。

您的情況直接由此報價覆蓋。換句話說,引用不是從通用聲明定義規則中排除的。您可以在其他地方爲已定義(和已初始化)的引用創建非定義聲明。

沒有人禁止您使用明確的extern關鍵字將初始化程序包含到引用聲明中。但是,像往常一樣,它會將一個非定義聲明變成一個定義定義

0
votes
answers
18 views
+10

某種生成循環

0

我有這樣一段代碼:某種生成循環

template<class T, class color_type> 
void assign_channels(T* ptr, const color_type& color) { 
    *(ptr + 0) = get_channel<0>(color); 

    if constexpr(1 < color_type::size) { 
     *(ptr + 1) = get_channel<1>(color); 
    } 
    if constexpr(2 < color_type::size) { 
     *(ptr + 2) = get_channel<2>(color); 
    } 
    if constexpr(3 < color_type::size) { 
     *(ptr + 3) = get_channel<3>(color); 
    } 
    if constexpr(4 < color_type::size) { 
     *(ptr + 4) = get_channel<4>(color); 
    } 
    if constexpr(5 < color_type::size) { 
     *(ptr + 5) = get_channel<5>(color); 
    } 
    if constexpr(6 < color_type::size) { 
     *(ptr + 6) = get_channel<6>(color); 
    } 
    if constexpr(7 < color_type::size) { 
     *(ptr + 7) = get_channel<7>(color); 
    } 
} 

它有兩個明顯的缺陷:

  1. ,除非我有不超過8個通道將無法正常工作;
  2. 它主要是樣板。

有沒有一種方式在C++中重寫它在某種類型的循環?我認爲一個反覆出現的模板結構可以完成這項工作,但它不是很可讀。我該怎麼辦?

+1

爲什麼'get_channel'是一個模板? o.0' – Alexander

+0

@Alexander這是一個長期以來運行時間最小化的真正靈活的'color_t'。 :| –

+0

表達'*(ptr + 5)'的更常見的方式是'ptr [5]'。 – nwp

沙发
0
4

使用摺疊表達式和std::index_sequence在C++ 17

template<class T, class color_type, size_t... Is> 
void assign_channels(T* ptr, const color_type& color, std::index_sequence<Is...>) { 
    ((ptr[Is] = get_channel<Is>(color)), ...); 
} 

template<class T, class color_type> 
void assign_channels(T* ptr, const color_type& color) { 
    assign_channels(ptr, color, std::make_index_sequence<color_type::size>{}); 
} 

此前C++ 17,你必須重寫倍的表達作爲遞歸。

0
votes
answers
18 views
+10

沒有意思的標準偏差C++

-2

我有一個功能強大的程序來查找許多整數的標準偏差。但是,我想找到一種方法來獲得沒有平均值的標準偏差。沒有意思的標準偏差C++

我理解的公式爲: 標準偏差= SQRT [(B - A^2/N)/ N]

其中

A是數據值的總和;

B是平方數據值的總和;

N是數據值的數量。

但我怎麼會寫在代碼? 這是我對偏差的功能,但它使用的意思是:

float calculateSD(int arr[]) 
{ 
float sum = 0.0, mean, standardDeviation = 0.0; 

int i; 

for(i = 0; i < SIZE; ++i) 
{ 
    sum += arr[i]; 
} 

mean = sum/SIZE; 

for(i = 0; i < SIZE; ++i) 
    //convert standardDeviation to float 
    standardDeviation += static_cast<float>(pow(arr[i] - mean, 2)); 
//return standard deviation 
return sqrt(standardDeviation/SIZE); 

}  
+0

'得到標準差不mean'我可以問爲什麼? – DimChtz

+0

家庭作業也許? – twoleggedhorse

+1

你有總和和數量。劃分.....來吧。 –

沙发
0
0
#include <iostream> 
#include <vector> 
#include <numeric> 
#include <math.h> 

double stddev(std::vector<int> const& data) 
{ 
    auto stats = std::make_pair(0.0,0.0); 
    stats = std::accumulate(data.begin(), data.end(), stats, 
          [](std::pair<double,double> stats, double x) { 
           stats.first += x; 
           stats.second += x * x; 
           return stats; 
          }); 
    return sqrt((stats.second - pow(stats.first, 2.0)/data.size())/data.size()); 
} 

int main(int argc, const char *argv[]) 
{ 
    std::cout << stddev({1,1,1,1}) << std::endl; 
    std::cout << stddev({1,2,1,2}) << std::endl; 
    std::cout << stddev({1,10,1,10}) << std::endl; 
} 
0
votes
answers
23 views
+10

C++ do-while循環

-10

夥計! 我正在用C++編寫一個程序來演示'do-while'循環。只要不是「再見」,該程序只會迴應用戶輸入的任何內容。 因此,如果用戶輸入'嘿',程序會迴應'嘿',如果用戶輸入'再見',程序將停止。這是代碼:C++ do-while循環

#include "stdafx.h" 
#include <iostream> 
#include <string> 

using namespace std; 

int main() 
{ 
string wordString; 

do 
{ 
    cout << "
Enter a word: "; 
    getline(cin, wordString); 
    cout << "
You entered: " << wordString<<"
"; 
} while ((wordString!="goodbye")||(wordString!="Goodbye")); 

return 0; 
} 

我想要做的是使程序停止當用戶輸入單詞「再見」或「再見。」所以我加了||檢查,但它不起作用,循環語句只是繼續執行。 但是當我把& &而不是||它工作正常,只要輸入「再見」或「再見」,程序就會停止。

所以我的問題是這樣的:爲什麼& &工作和||不?

+3

在一張紙上分配到'wordString'不同的值,看看有什麼每個條件評估爲。這是否真的需要關於SO的完整問題? – StoryTeller

+0

只需申請[德摩根法律](https://en.wikipedia.org/wiki/De_Morgan%27s_laws),你就會明白爲什麼。 – Jodocus

+0

邏輯;這個時間總是等於1。使用AND時,當任一條件爲0時,該時間將爲0. – JDQ

沙发
0
0

使用|| deosnot停止程序,因爲它是或運算符,這意味着它將是真實的,當任何人的聲明是真實的,所以如果任何人是真的,那麼它將執行另一方面在AND(& &)operator這意味着兩個聲明必須是真實的才能執行。

板凳
0
0

你必須使用logical and &&or ||因爲你想打破循環,如果只wordstring不等於RO「再見」,不等於「再見」:

while(wordString != "goodbye") && (wordString != "Goodbye"); 

或者您可以使用OR ||這樣:

while(wordString == "goodbye" || wordString == "Goodbye"); 

正如你可以看到,或者如果wordString包含無論是「再見」或「再見」,然後打破。如果兩個操作數均爲非零,則邏輯或返回true,如果兩者均爲零,則返回false。邏輯AND「& &」只返回true,如果兩個操作數非零,則返回flase(0)。

我可以看到,如果用戶輸入「再見」;資本中的第一個字母或小寫字母和大寫字母的混合,那麼你將編程將看起來很荒謬;因爲它不會中斷。

的解決方法是,你可以輸入文本轉換爲要麼全部大寫或小寫字母,然後僅選中一個值:

std::string wordString = "GoodBye"; 
for(int i(0); i < wordString.length(); i++) 
    wordString[i] = to_upper(wordString[i]); 

// wordString = "GOODBYE" 

// .... 
while(wordString != "GOODBYE"); 
0
votes
answers
17 views
+10

C++類型擦除與性狀

1

我想知道這是可能使符合性狀像這樣的擦除類型:C++類型擦除與性狀

template<class T> 
using read_t = std::conditional_t<true, 
    decltype(std::declval<T>().Read(uint16_t{})), 
    std::integral_constant<uint8_t (T::*)(uint16_t), &T::Read>>; 

,並用它這樣的嗎?

using any_readable_t = any<read_t>; 
auto test(any_readable_t &r) -> uint8_t { 
    return r.Read(0); 
} 
+0

它是'.read'還是'.Read'? – alfC

+0

這是。閱讀,我derped。 – uknys

+0

看看Boost.TypeErasure http://www.boost.org/doc/libs/1_65_1/doc/html/boost_typeerasure.html – alfC

沙发
0
1

沒有任何外部庫,需要做很多工作才能實現您想要的功能。使用Louis Dionne's dyno

DYNO_INTERFACE(Readable, 
    (read, uint8_t (uint16_t)) 
); 

auto test(Readable& r) -> uint8_t { 
    return r.read(0); 
} 
+0

是的,我知道這個庫,但我不能使它與CMake的工作,由於HanaConfig.cmake失蹤:/ – uknys

+0

@uknys:在GitHub上打開一個問題? https://github.com/ldionne/dyno/issues –

0
votes
answers
15 views
+10

CreateProcess()沒有正確啓動進程

0

我試圖簡單地啓動一個應用程序使用下面的函數,但它dosent似乎正常工作。它不會從桌面啓動我的測試應用程序,但是當我將它移動到「下載」中的子文件夾時,它工作正常。我拉從配置文件的目錄信息,並考慮到我可以從一個單獨的文件夾啓動測試應用程序,我懷疑它與我的目錄信息有任何關係。CreateProcess()沒有正確啓動進程

bool StartTest(){ 
    char WOW_PATH[MAX_PATH]; 
    char WOW_PATH_FULL[MAX_PATH]; 
    STARTUPINFO SUI; 
    PROCESS_INFORMATION PROCINFO; 

    SUI.cb   = sizeof(STARTUPINFO); 
    SUI.lpReserved = 0; 
    SUI.lpTitle  = 0; 
    SUI.dwFlags  = STARTF_RUNFULLSCREEN; 
    SUI.wShowWindow = SW_SHOW; 
    SUI.cbReserved2 = 0; 
    SUI.lpReserved2 = 0; 

    ZeroMemory(&PROCINFO,sizeof(PROCINFO)); 

    ifstream File; 
    File.open("config.txt"); 
    File.getline(WOW_PATH,MAX_PATH); 
    File.close(); 

    strcpy(WOW_PATH_FULL,WOW_PATH); 

    strcpy(WOW_PATH_FULL,"Test.exe"); 

    if(!CreateProcess(WOW_PATH_FULL,0,0,0,false,0,0,WOW_PATH,&SUI,&PROCINFO)) 
     return 0; 

    CloseHandle(PROCINFO.hProcess); 
    CloseHandle(PROCINFO.hThread); 

    return 1; 
} 
+2

也許你能告訴我們的日誌什麼WOW_PATH_FULL'的'的精確值是兩個工作和失敗的例子。另外,GetLastError()會說什麼? – 2013-04-26 02:15:16

+1

否'GetLastError'信息?在詢問之前試着找出什麼是錯的。 – 2013-04-26 02:23:55

沙发
0
3

我懷疑以下行需要有反斜槓轉義。第二個調用需要是strcat,而不是strcpy。

strcpy(WOW_PATH_FULL,WOW_PATH); 
strcpy(WOW_PATH_FULL,"Test.exe"); 

這裏的修復:

strcpy(WOW_PATH_FULL,WOW_PATH); 
strcat(WOW_PATH_FULL,"\Test.exe"); 
+1

另外,請查看Win32幫助函數,PathAppend或其派生之一。它會自動爲您處理反斜槓。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb773565%28v=vs.85%29.aspx – selbie 2013-04-26 02:31:41

+0

或者只是使用'/' - Windows作爲路徑分隔符是完全正確的。 – 2013-04-26 02:39:18

+0

另外 - 我不知道爲什麼當使用「子文件夾在下載」它的工作? – 2013-04-26 02:41:44

0
votes
answers
42 views
+10

Boost多線程

4

任何人都可以告訴這裏發生了什麼?當我嘗試調試代碼時,以及控件位於第15行的thread()函數中時,它會跳過第16行移動到第17行並返回第16行。爲什麼它不會逐行移動?Boost多線程

1. #include <boost/thread.hpp> 
2. #include <iostream> 
3. 
4. void wait(int seconds) 
5. { 
6. boost::this_thread::sleep(boost::posix_time::seconds(seconds)); 
7. } 
8. 
9. boost::mutex mutex; 
10. 
11. void thread() 
12. { 
13. for (int i = 0; i < 5; ++i) 
14. { 
15. wait(1); 
16. mutex.lock(); 
17. std::cout << "Thread " << boost::this_thread::get_id() << ": " << i << std::endl; 
18. mutex.unlock(); 
19. } 
20. } 
21. 
22. int main() 
23. { 
24. boost::thread t1(thread); 
25. boost::thread t2(thread); 
26. t1.join(); 
27. t2.join(); 
28. } 
沙发
0
5

可能你的調試器實際上並行地執行幾個線程,這就是它爲什麼會跳來跳去。嘗試從您的調試器打印線程ID,您可能會在每個站點看到不同的數字。

調試中出現奇怪跳躍的另一個原因是代碼已經優化。如果是這樣,則源代碼順序不會與編譯代碼匹配

板凳
0
0

當您的輸出跳轉時,您的輸出是什麼樣的?它看起來可能是多線程問題。